如何在对象上调用setter方法(强制类型)

时间:2013-12-04 04:58:52

标签: java clojure

我希望编写一个与java对象交互的函数

(assoc-obj <object> "<Prop1>" <Val1> "<Prop2>" <Val2>)

相同
(doto <object>
     (.set<Prop1> <Val1>)
     (.set<Prop2> <Val2>))

我正在使用反思:

(let [method (->> 
              (seq (.getMethods java.util.Date))
              (filter #(= "setDate" (.getName %)))
              first)
      arr (object-array 1)
      _   (aset arr 0 (int 1))
      d   (java.util.Date.)]
  (.invoke method d arr)
  d)

但我发现类型强制存在问题。

这样做有更好/更多的方式吗?

2 个答案:

答案 0 :(得分:1)

我使用clojure.lang.Reflector/invokeInstanceMethod。这是一个REPL演示:

user=> (def d (java.util.Date.))
#'user/d
user=> d
#inst "2013-12-04T05:47:33.560-00:00"
user=> (clojure.lang.Reflector/invokeInstanceMethod
        d "setDate" (object-array (list 1)))
nil
user=> d
#inst "2013-12-01T05:47:33.560-00:00"

我认为反射器的所有内容都是一个实现细节(偶尔会对方法签名进行调整等),但这种功能在Clojure中是必要的,可以采用某种形式。

答案 1 :(得分:1)

通过查看您显示的示例,这似乎是一个简单的代码转换,为什么不是宏?

(defmacro assoc-obj [obj & props]
  (let [psets (map (fn [[p v]] (list (symbol (str ".set" p)) v ))
                   (partition 2 props))]
    `(doto ~obj ~@psets)))