在Clojure中动态访问Java字段?

Ann*_*nan 7 interop clojure

我是clojure和java的新手.

为了访问Clojure中的Java字段,您可以:

Classname/staticField
Run Code Online (Sandbox Code Playgroud)

这是一样的

(. Classname staticField)
Run Code Online (Sandbox Code Playgroud)

(如我错了请纠正我)

当变量中保存的字段名称时,如何访问静态字段?即:

(let [key-stroke 'VK_L
      key-event KeyEvent/key-stroke])
Run Code Online (Sandbox Code Playgroud)

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

sku*_*uro 10

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

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

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


Joo*_*aat 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}
Run Code Online (Sandbox Code Playgroud)

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


jk.*_*jk. 5

反思可能是正确的途径,但最简单的方法是

(eval (read-string (str "KeyEvent/" key-stroke)))
Run Code Online (Sandbox Code Playgroud)

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