2013-04-10 23 views
8

我需要以某种方式将某些Clojure函数标记为“特殊”,以便Java代码可以使用反射来识别它们。我试图给函数添加注释,但显然不支持。我试过reify一个扩展为IFn的接口(以便Java代码可以识别函数对象),但这并不好,因为Clojure没有直接使用实现方法作为实现invoke的代码,而是直接调用Afunction实际实现该方法的对象(我需要用实际功能代码标记实际的invoke方法)。我如何标记一个Clojure函数,以便我可以用Java反射识别它

任何想法?

编辑:甚至可以用ASM库(而不是常规反射)访问的方式标记会很好,但我需要以某种方式标记实际的AFunction对象或invoke方法。另外,我无法访问实际的AFunction对象 - 我需要该标记在课程中可见。

回答

3

可以使用的Clojure元数据功能,它允许元数据(地图),以附接至实现IMeta接口(其结果是每一个对象作为IObj延伸IMeta和每一个对象延伸IObj)任何对象

现在有2个选项。

1)您可以将元数据附加到VAR(风险价值指向实际IFN对象)

(defn hello {:name "hello"} [] 10) 

,并在Java方面你得到的VAR打招呼的持有和使用IMeta方法来获取元数据并检测您的特定元数据是否存在。 这个问题可能是你的Java代码直接访问/处理IFn对象而不是它们的变量(例如:匿名函数),为了解决这个问题,试试第二种方法。

2)安装元数据的功能对象本身:

(def hello (with-meta (fn [] 10) {:name "hello"})) 

不能使用defn作为元数据附加到变量。上面的示例代码将元数据附加到函数对象本身。在Java方面,将函数对象转换为IMeta并执行检查。 上面的代码可以做得更多defn比较与作为一个练习剩下的宏的帮助:)

+0

谢谢!不幸的是,我甚至无法访问IFn对象 - 仅限于它的类。我需要以某种方式标记这个类(我甚至不需要附加任何特定的信息,只是以某种方式确定该类是否被“标记”)。我想通过让invoke方法指定它引发一个众所周知的检查异常来标记它,但是我不知道从Clojure那里做这件事。 – pron 2013-04-10 12:44:35

+0

你能否提供一些clojure和java的示例代码来展示如何从clojure创建类并从Java访问,因为这会使问题更加清晰 – Ankur 2013-04-10 12:46:23

+0

我使用JavaAgent来测试某些类。我会在加载新课程时收到通知。我想以某种方式标记Clojure函数,以便知道它是否需要检测。 – pron 2013-04-10 12:48:41

0

事实证明,如果你用一个包含本地定义的let语句包含函数体,变量名将出现在类文件的方法本地表中。虽然有点麻烦。仍在寻找更好的方法。

相关问题