开发者

Using type hints in Clojure for Java return values

I'm working on some Java / Clojure interoperability and came across a reflection warning for the following code:

(defn load-image [resource-name]
  (javax.imageio.ImageIO/read 
    (.getResource 
      (class javax.imageio.ImageIO) 
      resource-name)))

=> Reflection warning, clojure/repl.clj:37 - reference to field read can't be resolved.

I'm surprised at this because getResource always returns a URL and I would therefore expect the compiler to use the appropriate static method in ja开发者_运维技巧vax.imageio.ImageIO/read.

The code works fine BTW so it is clearly finding the right method at run time.

So two questions:

  1. Why is this returning a reflection warning?
  2. What type hint do I need to fix this?


AFAICS has this nothing to do with your code or compilation. It is part of the source-fn function of the REPL :

 ...
      (let [text (StringBuilder.)
            pbr (proxy [PushbackReader] [rdr]
                  (read [] (let [i (proxy-super read)]
                             (.append text (char i))
                             i)))]
 ...

and used to display source code in the REPL shell, AFAICT.


For others who find this post (as I did) when wondering why they get reflection warnings when using proxy-super...

Every proxy method has an implicit this first arg, which, alas, is not type-hinted (presumably because there are a number of possible types being implemented by the proxy and the resultant proxy class is created later).

So, if you ever call methods on this from inside the proxy (which is what proxy-super ends up doing), then you'll see reflection warnings.

The simple solution is to just wrap your code in a let that uses type-hinting. E.g.:

(let [^SomeClass this this]
  (proxy-super foo)
  (.bar this))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜