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"
我可以执行以下操作并且有效...
=> (. 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"