Clojure:在编译时不知道arg类型就调用.invoke

时间:2017-08-21 03:25:18

标签: javafx clojure javafx-8

我正试图找出一种方法来处理单个arg的.invoke()方法,而不知道运行时arg的类型。

例如,通过将属性名称传递给以下函数,我想设置属性的值。现在它被硬编码为Double/TYPE,但实际上应该允许该函数采用任何类型的value arg。

在运行时之前,属性名称以及arg value的类型是未知的,但是看起来该方法需要一组基元,至少对于数字类型而言。

(defn set-prop-val!
  "Sets property value to value.  Uses reflection."
  [obj prop value]
  (let [methodname (str "set" prop)]
    (.. obj
        getClass
        (getMethod methodname (into-array [Double/TYPE]))
        (invoke obj (into-array [value]) ))))

(set-prop-val! (Button.) "TranslateX" 13.99)

在上述功能中,尝试改为(getMethod methodname (into-array [(class value)]))不起作用,我得到NoSuchMethodException javafx.scene.control.Button.setTranslateX(java.lang.Double),因为它需要double而不是Double

我想要做的是数字在运行时获取原始类型,但是从实例调用静态方法的所有尝试都失败了,例如(. (class 19.5) TYPE)(在这种情况下,我得到{{1} }})

即使IllegalArgumentException No matching field found: TYPE for class java.lang.Class返回Double/TYPE,似乎只有(= (class 19.5) Double)才有效。

因此提出了一些问题:

  1. 如何从实例中调用静态方法,例如true
  2. TYPE这里有用吗?这将为我提供数组以携带double-array的值,这甚至不是必需的,但不是.invoke所需的Class[double]数组。
  3. 我应该使用.getMethod吗?

1 个答案:

答案 0 :(得分:1)

我发现我可以使用clojure.lang.Reflector/invokeInstanceMethod完全按照我的需要做。