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

0 votes
ago in Java Interop by
edited ago by

I have the function

(defn println-err [^String s]
  (.println *err* s))

When I set *warn-on-reflections*, I get
> call to method println can't be resolved (target class is unknown).

I can work around this with (binding [*out* *err*] (println s))), but I'd like to know why I'm getting this reflection warning even though I'm telling the compiler the type.

Note: I have zero Java experience.

2 Answers

+1 vote
ago by
selected ago by
 
Best answer

You could type hint the target (which is what the warning is about, not the argument types):

user=> (type *err*)
java.io.PrintWriter
user=> (.println ^java.io.PrintWriter *err* "foo")
foo
nil

I suspect this is because *err* is a dynamically bound var so the compiler doesn't know its type, even tho' the bound value is java.io.PrintWriter.

You could also use the new-in-1.12 qualified method access, to avoid the warning:

user=> (set! *warn-on-reflection* true)
true
user=> (.println *err* "foo")
Reflection warning, NO_SOURCE_PATH:1:1 - call to method println can't be resolved (target class is unknown).
foo
nil
user=> (import 'java.io.PrintWriter)
java.io.PrintWriter
user=> (PrintWriter/.println *err* "foo")
foo
nil
ago by
Thanks! I'm already importing java.io.File, so that second option works out nicely.
+1 vote
ago by

target class is unknown

The "target" here means *err*.

ago by
Oh... Thanks! `^java.in.PrintWriter *err*` fixed it.
...