Welcome! Please see the About page for a little more info on how this works.

+4 votes
in Java Interop by

Hi everyone,
I was playing around with java-interop and found this:

(set! *warn-on-reflection* true)

(defonce ^:private ^ScheduledExecutorService executor (Executors/newScheduledThreadPool 1))

(defn set-timeout-primitive ^ScheduledFuture [^long ms ^Callable f]
  (.schedule executor f ms TimeUnit/MILLISECONDS))

(defn set-timeout-object ^ScheduledFuture [^Long ms ^Callable f]
  (.schedule executor f ms TimeUnit/MILLISECONDS))

(.get (set-timeout-primitive 2000 (fn [] (println :done) :done))) ; Reflection warning, ... - reference to field get on java.lang.Object can't be resolved.
(.get (set-timeout-object 2000 (fn [] (println :done) :done))) ; No warnings

The reason for this reflection warning (thanks for explaining) seems to be that when the compiler looks for the matching interface it finds this:

static public interface OLOO{Object invokePrim(Object arg0, long arg1, Object arg2);}

So the return value becomes an Object and not a ScheduledFuture. But this doesn't happen when using a ^Long type hint instead of a ^long.

Could this be improved? Thank you!

1 Answer

+3 votes
selected by
Best answer

This happens because when the compiler converts a VarExpr invocation into an invokePrim expression, it loses the type hint from the arglist. I already have a patch for this if this gets converted into a JIRA ticket.

Feel free to make the jira yourself if you like... we'll get to it eventually if not