开发者

Options for creating Java classes in Clojure

There are a few different ways to create Java classes in Clojure, so what are the tradeoffs when picking between gen-class, proxy, and reify in Clojure? (are there other ways to create Java classes that I haven't listed?)

My basic understanding is that I hav开发者_JAVA百科e listed these constructs in decreasing order of power.


Use gen-class when you want a named class or you want to add new methods to objects you create. gen-class relies on AOT compilation.

When you want an anonymous, one-off implementation of a type you use reify or proxy. They do not rely on AOT compilation. Here are their differences:

  1. reify only supports protocols or interfaces, proxy also supports concrete superclasses.
  2. reify uses true class methods, proxy uses external functions.
  3. Because of #2, reify uses direct method lookup, while proxy uses a map for method lookup.
  4. Because of #3, reify does not support dynamic swapping of methods, but proxy does.

reify will perform better than proxy, so you should always use reify when possible. Only use proxy when reify's constraints are too prohibitive.


In addition to gen-class, proxy and reify, we have defrecord and deftype. These latter two options should be your first choices for the creation of named java classes (and in the case of defrecord, your first choice for any kind of struct with named components.)

The datatypes page on clojure.org is a good reference on this topic. Defrecord, deftype and reify are newer than gen-class and proxy, having been introduced in version 1.2 (I think -- possibly 1.1). Defrecord and deftype both create classes that conform to interfaces, but do not allow for inheritance. If you need inheritance, gen-class (and proxy for anonymous classes) is still your only option.

Defrecord and deftype differ in what you are given for free. Defrecord automatically creates a class which conforms to IPersistentMap and ISeq. Deftype, on the other hand, gives you more control over your class, even allowing for mutable fields (not allowed in defrecord). In general, deftype is intended for low-level implementation of data structures, whereas defrecord is intended for most day-to-day use.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜