Использование подсказок типов в Clojure для возвращаемых значений Java - PullRequest
11 голосов
/ 02 июня 2010

Я работаю над некоторой совместимостью 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.

Кстати, код прекрасно работает, поэтому он четко находит правильный метод во время выполнения.

Итак, два вопроса:

  1. Почему это возвращает предупреждение об отражении?
  2. Какой тип подсказки мне нужно исправить?

Ответы [ 2 ]

4 голосов
/ 02 июня 2010

AFAICS не имеет ничего общего с вашим кодом или компиляцией. Он является частью функции source-fn REPL:

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

и используется для отображения исходного кода в оболочке REPL, AFAICT.

2 голосов
/ 25 июня 2010

Для тех, кто находит этот пост (как и я), задаваясь вопросом, почему они получают предупреждения об отражении при использовании proxy-super ...

Каждый прокси-метод имеет неявный this первый аргумент, который, увы,, не намекается на тип (предположительно потому, что прокси-сервер реализует несколько возможных типов, а результирующий класс прокси создается позже).

Итак, если вы когда-либо вызываете методы из this изнутрипрокси (это то, что proxy-super в конечном итоге делает), тогда вы увидите предупреждения об отражении.

Простое решение - просто обернуть ваш код в let, который использует подсказки типов.Например:

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