Access Java fields dynamically in Clojure?

我的梦境 提交于 2019-12-01 16:47:12

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.

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

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.

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