Clojure:通过实例变量或字符串(不是类名符号)调用Java静态方法/字段

问题描述 投票:1回答:2

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

=> (. 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,并搜索了堆栈溢出。问题here不同。

clojure static-methods clojure-java-interop
2个回答
1
投票

就像在Java中一样,只有在编译时知道要调用哪种类的方法时,才可以直接调用静态方法。否则,您需要在Class对象上使用反射来查找方法句柄。


0
投票

这里是尝试使用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"
© www.soinside.com 2019 - 2024. All rights reserved.