【问题标题】:How do I tag a Clojure function so that I could recognize it with Java reflection如何标记 Clojure 函数,以便我可以使用 Java 反射识别它
【发布时间】:2013-04-02 04:51:42
【问题描述】:

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

有什么想法吗?

编辑:即使以可以使用 ASM 库(而不是常规反射)访问的方式进行标记也可以,但我需要以某种方式标记实际的 AFunction 对象或 invoke 方法。另外,我无法访问实际的 AFunction 对象——我需要标签在类上可见。

【问题讨论】:

    标签: clojure clojure-java-interop


    【解决方案1】:

    事实证明,如果用包含局部定义的 let 语句将函数体括起来,则该变量名称将出现在类文件中方法的局部表中。不过有点麻烦。仍在寻找更好的方法。

    【讨论】:

      【解决方案2】:

      您可以使用 clojure 元数据功能,该功能允许将元数据(映射)附加到任何实现 IMeta 接口的对象(结果是每个对象,因为 IObj 扩展 IMeta 并且每个对象扩展 IObj)

      现在有 2 个选项。

      1) 您可以将元数据附加到 var(var 指向实际的 IFn 对象)

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

      在 Java 端,您获取 var hello 并使用 IMeta 方法获取元数据并检测您的特定元数据是否存在。 这个问题可能是您的 Java 代码直接访问/处理 IFn 对象而不是它们的变量(例如:匿名函数),要解决这个问题,请尝试第二个选项。

      2) 将元数据附加到函数对象本身:

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

      您不能使用 defn 将元数据附加到 var。上面的示例代码将元数据附加到函数对象本身。在 Java 端,将函数对象类型化为 IMeta 并进行检查。 上面的代码可以在作为练习的宏的帮助下变得更defn likish :)

      【讨论】:

      • 谢谢!不幸的是,我什至无法访问 IFn 对象本身——只能访问它的类。我需要以某种方式标记该类(我什至不需要附加任何特定信息,只是一种确定该类是否以某种方式“标记”的方法)。我想通过让调用方法指定它抛出一个众所周知的检查异常来标记它,但我不知道从 Clojure 中这样做。
      • 您能否提供一些 clojure 和 java 的示例代码,以展示如何从 Java 创建和访问 clojure 中的类,因为这样可以使问题更清楚
      • 我使用 JavaAgent 来检测一些类。加载新类时会通知我。我想以某种方式标记一个 Clojure 函数,以便我知道它是否需要检测。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      • 2010-12-04
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 1970-01-01
      相关资源
      最近更新 更多