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

在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

我正在研究一些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中使用适当的静态方法

顺便说一句,代码运行良好,因此在运行时显然找到了正确的方法

所以有两个问题:

  • 为什么会返回反射警告
  • 我需要什么类型的提示来修复此问题

  • 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)行之前,警告就会消失,那么可能发生的情况是,这会改变编译的时间?