在Clojure中使用类型提示获取Java返回值

时间:2010-06-01 22:53:15

标签: java clojure type-hinting

我正在开发一些Java / Clojure互操作性,并遇到以下代码的反射警告:

(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.

我对此感到惊讶,因为getResource总是返回一个URL,因此我希望编译器在javax.imageio.ImageIO / read中使用适当的静态方法。

代码工作正常BTW,因此很明显在运行时找到了正确的方法。

所以有两个问题:

  1. 为什么会返回反射警告?
  2. 我需要提供哪种类型的提示才能解决此问题?

2 个答案:

答案 0 :(得分:4)

AFAICS与您的代码或编译无关。它是REPL的source-fn函数的一部分:

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

用于在REPL shell中显示源代码,AFAICT。

答案 1 :(得分:2)

对于其他发现这篇文章的人(就像我一样)在想知道为什么他们在使用proxy-super时会得到反映警告......

每个代理方法都有一个隐式this第一个arg,唉,它不是类型提示的(大概是因为代理实现了许多可能的类型,后来创建了结果代理类)

所以,如果你从代理内部调用this上的方法(这是proxy-super最终做的事情),那么你会看到反射警告。

简单的解决方案是将代码包装在使用类型提示的let中。 E.g:

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