在Clojure中为Java返回值使用类型提示
我正在研究一些Java/Clojure互操作性,遇到了以下代码的反射警告:在Clojure中为Java返回值使用类型提示,java,clojure,type-hinting,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 r
(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中使用适当的静态方法
顺便说一句,代码运行良好,因此在运行时显然找到了正确的方法
所以有两个问题:
AFAICS与您的代码或编译无关。它是REPL的源fn函数的一部分:
...
(let [text (StringBuilder.)
pbr (proxy [PushbackReader] [rdr]
(read [] (let [i (proxy-super read)]
(.append text (char i))
i)))]
...
并用于在REPL shell AFAICT中显示源代码 对于其他人,当他们想知道为什么在使用
proxy super
时会收到反射警告时,会发现这篇文章(就像我所做的那样)
每个代理方法都有一个隐式的this
first arg,唉,它不是类型暗示的(可能是因为代理正在实现许多可能的类型,并且生成的代理类稍后创建)
因此,如果您曾经从代理内部调用this
上的方法(这就是proxy super
最终要做的),那么您将看到反射警告
简单的解决方案是将代码包装在使用类型提示的let
中。例如:
(let [^SomeClass this this]
(proxy-super foo)
(.bar this))
我没有收到此代码的反射警告。你能提供更多关于你的设置的细节吗?(Clojure版本——尽管我尝试了1.1和Leading edge——至少也尝试了JVM版本。)我正在使用Clojure 1.2和Java 1.6 JDK的五月中旬版本。也许我应该试试最新的1.2版本?Sun JDK还是OpenJDK?至于构建,当然,试一试,尽管它对我自己的本地构建和1.1版本的.sunjdk都有效——但根据Peter下面的回答,它似乎是REPL代码中的问题,而不是上面的代码。所以希望在最新的1.2版本中有一个已经修复了,这真的是在做正确的事情吗?(类javax.imageio.imageio)是类。如果您想要ImageIO类,只需直接使用它:(.getResource javax.ImageIO.ImageIO resource name)。非常好!我猜这是Clojure开发团队需要解决的警告?反射警告在编译时发出。当任何东西都可以输入到REPL中时,REPL代码当然已经完成了编译。事实上,
clojure.jar
中的内容是提前编译的,所以我看不出任何与之相关的反射警告会在REPL中出现。此外,我仍然无法重现这个问题,我尝试了当前的Hudson快照、两个本地1.2版本和1.1版本jar。只是想给游行带来一些建设性的雨,以帮助扫除我们理解这一点的任何剩余障碍……它似乎在repl.clj中抱怨的一句话是:(proxy[PushbackReader][rdr](read[](let[i(proxy super read)](.append text(char i))i)-有趣的是,我注意到,如果我将ns声明中的(:use[clojure.repl])放在(set!warn on reflection true)行之前,警告就会消失,那么可能发生的情况是,这会改变编译的时间?