Clojure:通过实例变量或字符串调用 java static method/field(不是 class 名称符号)

Clojure: call java static method/field via instance variable or string (not class name symbol)

我可以执行以下操作并且有效...

=> (. java.awt.event.KeyEvent getKeyText 10)
"Enter"

但是,我有一个名为 ev 的 java.awt.event.KeyEvent 实例。例如,

=> (class ev)
java.awt.event.KeyEvent

我想改为这样调用方法(但是,这会产生错误):

=> (. (class ev) getKeyText 10)
No matching method getKeyText found taking 1 args for class java.lang.Class

是否可以从实例调用静态方法?

我看过docs and searched stack overflow. The question here不一样

就像在Java中一样,只有在编译时知道要调用什么class什么方法的情况下,才能直接调用静态方法。否则,您需要在 Class 对象上使用反射来查找方法句柄。

这是使用 MethodHandle API 的尝试。

(ns playground.static-method-handle
  (:import [java.lang.invoke MethodType MethodHandles]))

;; Get a MethodType instance that encodes the shape of the method (return type and arguments)
(def getKeyText-method-type (MethodType/methodType String Integer/TYPE))

(defn call-getKeyText-on-class [cl key-code]
  (let [lu (MethodHandles/lookup)
        h (.findStatic lu cl "getKeyText" getKeyText-method-type)]
    (.invokeWithArguments h [(int key-code)])))

我们这样使用它:

(call-getKeyText-on-class KeyEvent 10)
;; => "Enter"