在Clojure中创建Java类的选项

时间:2011-04-29 11:47:03

标签: clojure clojure-java-interop

在Clojure中创建Java类有几种不同的方法,那么在Clojure中在gen-classproxyreify之间进行选择时有什么权衡? (还有其他方法可以创建我没有列出的Java类吗?)

我的基本理解是我已经按照权力的递减顺序列出了这些结构。

2 个答案:

答案 0 :(得分:18)

如果需要命名类,或者要为要创建的对象添加新方法,请使用gen-classgen-class依赖于AOT编译。

如果您想要使用reifyproxy进行匿名,一次性的类型实施。他们不依赖于AOT编译。以下是他们的不同之处:

  1. reify仅支持协议或接口,proxy也支持具体的超类。
  2. reify使用真正的类方法,proxy使用外部函数。
  3. 由于#2,reify使用直接方法查找,而proxy使用地图进行方法查找。
  4. 由于#3,reify不支持动态交换方法,但proxy会这样做。
  5. reify的效果优于proxy,因此您应该尽可能使用reify。仅在proxy的约束过于严格时才使用reify

答案 1 :(得分:10)

除了gen-class,proxy和reify之外,我们还有defrecord和deftype。后两个选项应该是创建命名java类的第一选择(在defrecord的情况下,对于任何具有命名组件的结构的首选。)

datatypes page on clojure.org是这个主题的一个很好的参考。 Defrecord,deftype和reify比gen-class和proxy更新,已经在版本1.2中引入(我认为 - 可能是1.1)。 Defrecord和deftype都创建符合接口的类,但不允许继承。如果你需要继承,gen-class(和匿名类的代理)仍然是你唯一的选择。

Defrecord和deftype在免费赠送的内容上有所不同。 Defrecord自动创建一个符合IPersistentMap和ISeq的类。另一方面,Deftype可以让您更好地控制您的类,甚至允许可变字段(在defrecord中不允许)。通常,deftype用于数据结构的低级实现,而defrecord用于大多数日常使用。