【问题标题】:Clojure call to static Java method of anonymous classClojure调用匿名类的静态Java方法
【发布时间】:2017-06-26 20:46:04
【问题描述】:

我有一组 Java 类,它们都实现了 newBuilder 接口(它们实际上是 protobuf 生成的类)。我想将该类作为参数传递给一个表单,该表单返回一个函数来为该类创建一个新的构建器。

(defn create-message-builder
  [klass]
  (. klass newBuilder))

我无法动态获取表单,因此它会调用klass 上的newBuilder 静态方法。

我在another SO post 上找到了一个宏,并进行了一些修改以支持将其注入到我的源代码中:

(defmacro jcall [obj & args]
  `(let [ref (if (and (symbol? ~obj) 
                     (instance? Class (eval ~obj)))
          (eval ~obj)
          ~obj) ]
  (. ref# ~@args)))

当我尝试调用这个宏时:

repl> (jcall Contact newBuilder)
#object[com.skroot.Contact$Builder 0x5622de90 ""]

我收到一个错误:

IllegalArgumentException 未找到匹配字段:类 java.lang.Class 的 newBuilder

【问题讨论】:

  • 而且它根本不是一个匿名类。您只是在编译时不知道它的名称,因为您在运行时传递了一个 Class 对象。

标签: clojure clojure-java-interop


【解决方案1】:

与在 Java 中所做的相同:使用反射来询问 Class 对象它有哪些方法,找到正确名称的方法,然后不带参数地调用它。

(defn class->builder [c]
  (let [m (.getDeclaredMethod c "newBuilder" (into-array Class []))]
    (.invoke m nil (into-array Object []))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多