Clojure で Java クラスを作成するには、いくつかの方法がgen-class
ありproxy
ますreify
。(私がリストしていない Java クラスを作成する他の方法はありますか?)
私の基本的な理解は、これらの構造を力の降順でリストしたということです。
gen-class
名前付きクラスが必要な場合、または作成したオブジェクトに新しいメソッドを追加する場合に使用します 。gen-class
AOT コンパイルに依存します。
reify
またはを使用する型の匿名の 1 回限りの実装が必要な場合proxy
。それらは AOT コンパイルに依存しません。それらの違いは次のとおりです。
reify
プロトコルまたはインターフェースのみをサポートし、proxy
具体的なスーパークラスもサポートします。reify
真のクラス メソッドをproxy
使用し、外部関数を使用します。reify
直接メソッド ルックアップをproxy
使用しますが、メソッド ルックアップにはマップを使用します。reify
メソッドの動的スワップをサポートしていませんが、サポートproxy
しています。reify
は よりも優れたパフォーマンスを発揮するため、可能なproxy
場合は常に使用する必要がありますreify
。の制約が厳しすぎるproxy
場合にのみ使用してください。reify
gen-class、proxy、reifyに加えて、defrecordとdeftypeがあります。これらの後者の2つのオプションは、名前付きJavaクラスを作成するための最初の選択肢です(defrecordの場合は、名前付きコンポーネントを持つあらゆる種類の構造体の最初の選択肢です)。
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はほとんどの日常的な使用を目的としています。