2011-04-29 59 views
13

在Clojure中創建Java類有幾種不同的方式,那麼Clojure中的gen-classproxyreify之間的選擇有什麼折衷? (有沒有其他方法可以創建我沒有列出的Java類?)在Clojure中創建Java類的選項

我的基本理解是我已經按照權力的降序列出了這些構造。

回答

18

使用gen-class當你想要一個命名的類,或者你想添加新的方法到你創建的對象。 gen-class依賴於AOT編譯。

當你想要一個匿名的,一次性實現你使用的類型reifyproxy。他們不依賴AOT編譯。以下是它們的區別:

  1. reify只支持協議或接口,proxy也支持具體的超類。
  2. reify使用真正的類方法,proxy使用外部函數。
  3. 由於#2,reify使用直接方法查找,而proxy使用映射進行方法查找。
  4. 由於#3的原因,reify不支持動態交換方法,但proxy的確如此。

reify將執行比proxy好,所以你應該總是使用reify時,應儘可能。當reify的限制過於禁止時,僅使用proxy

10

除了gen-class,proxy和reify,我們還有defrecord和deftype。後面這兩個選項應該是您創建命名java類的第一選擇(在defrecord的情況下,您是任何具有命名組件的結構的首選)。

datatypes page on clojure.org是關於此主題的很好參考。 defrecord,deftype和reify比1.2版本中引入的gen-class和proxy更新(我認爲 - 可能是1.1)。 Defrecord和deftype都創建符合接口的類,但不允許繼承。如果你需要繼承,gen-class(和匿名類代理)仍然是你唯一的選擇。

Defrecord和deftype的區別在於你免費贈送的東西。 Defrecord自動創建一個符合IPersistentMap和ISeq的類。另一方面,Deftype可以讓你更好地控制你的課程,甚至允許可變字段(不允許在defrecord中)。一般來說,deftype用於數據結構的低級實現,而defrecord則用於大多數日常使用。