Access Java fields dynamically in Clojure?

旧街凉风 提交于 2019-12-04 03:16:08

问题


I'm a novice in clojure and java.

In order to access a Java field in Clojure you can do:

Classname/staticField

which is just the same as

(. Classname staticField)

(correct me if I'm wrong)

How can I access a static field when the name of the field in held within a variable? i.e.:

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

I want key-stroke to be evaluated into the symbol VK_L before it tries to access the field.


回答1:


In this case you might want to do something like the following:

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

If you feel like it's a bit hack-ish, it's because it really is such. There might be better ways to structure the code, but at least this should work.




回答2:


I made a small clojure library that translates public fields to clojure maps using the reflection API:

(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}

See https://github.com/joodie/clj-java-fields




回答3:


Reflection is probably the proper route to take, but the easiest way is

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

This will just convert the generated string into valid clojure and then evaluate it.




回答4:


You can construct the right call as an s-expression and evaluate it as follows:

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

However, if what you are trying to do is test whether a particular key has been pressed, you may not need any of this: I usually find that it is easiest to write code something like:

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


来源:https://stackoverflow.com/questions/6630432/access-java-fields-dynamically-in-clojure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!