在Clojure中动态访问Java字段?

时间:2011-07-08 20:56:46

标签: interop clojure

我是clojure和java的新手。

为了访问Clojure中的Java字段,您可以执行以下操作:

Classname/staticField

相同
(. Classname staticField)

(如果我错了,请纠正我)

如果在变量中保留字段的名称,我该如何访问静态字段?,即:

(let [key-stroke 'VK_L
      key-event KeyEvent/key-stroke])

我希望key-stroke在尝试访问该字段之前将其评估为符号VK_L。

4 个答案:

答案 0 :(得分:10)

在这种情况下,您可能希望执行以下操作:

user=> (def m 'parseInt)          
#'user/m
user=> `(. Integer ~m "10")       
(. java.lang.Integer parseInt "10")
user=> (eval `(. Integer ~m "10"))
10

如果你觉得它有点像黑客,那是因为它确实如此。可能有更好的方法来构建代码,但至少这应该有效。

答案 1 :(得分:6)

我制作了一个小型的clojure库,使用反射API将公共字段转换为clojure地图:

(ns your.namespace
 (:use nl.zeekat.java.fields))

(deftype TestType
    [field1 field2])

; fully dynamic:

(fields (TestType. 1 2)) 
=> {:field1 1 :field2 2}

; optimized for specific class:
(def-fields rec-map TestType)

(rec-map (TestType. 1 2)) 
=> {:field1 1 :field2 2}

请参阅https://github.com/joodie/clj-java-fields

答案 2 :(得分:4)

反思可能是正确的选择,但最简单的方法是

(eval (read-string (str "KeyEvent/" key-stroke)))

这只会将生成的字符串转换为有效的clojure,然后对其进行评估。

答案 3 :(得分:1)

您可以将正确的调用构建为s-expression,并按如下方式对其进行评估:

(let [key-stroke 'VK_L
      key-event (eval `(. KeyEvent ~key-stroke))]
  ....do things with your key-event......)

但是,如果你要做的是测试是否按下了某个特定键,你可能不需要这样做:我通常发现编写类似的代码最简单:

(cond
  (= KeyEvent/VK_L key-value) 
    "Handle L"
  (= KeyEvent/VK_M key-value) 
    "Handle M"
  :else
    "Handle some other key")