私はC++ での静的メタプログラミングのファンです。Javaにはジェネリックがあることを知っています。これは、静的なメタプログラミング (つまり、コンパイル時のプログラム実行) が Java で可能であることを意味しますか? もしそうなら、誰かがそれについてもっと学ぶことができる良いリソースを推薦できますか?
11 に答える
いいえ、これは不可能です。ジェネリックはテンプレートほど強力ではありません。たとえば、テンプレート引数は、ユーザー定義型、プリミティブ型、または値にすることができます。ただし、ジェネリック テンプレート引数はObject
またはそのサブタイプのみです。
編集:これは古い回答です。2011 年以降、このようなトリックに使用できるアノテーションを備えた Java 7 があります。
Clojureを見てください。これは、JVM上で実行され、Javaと非常に相互運用可能なマクロ(メタプログラミング)を備えたLISPです。
「静的メタプログラミング」とはどういう意味ですか?はい、JavaではC ++テンプレートメタプログラミングは不可能ですが、C++のメソッドよりもはるかに強力な他のメソッドを提供します。
- 反射
- アスペクト指向プログラミング(@AspectJ)
- バイトコード操作(Javassist、ObjectWeb ASM、Javaエージェント)
- コード生成(注釈処理ツール、Velocityなどのテンプレートエンジン)
- 抽象構文ツリー操作(一般的なIDEによって提供されるAPI)
- Javaコンパイラを実行し、実行時にもコンパイルされたコードを使用する可能性
最善の方法はありません。これらの方法にはそれぞれ長所と短所があります。JVMの柔軟性により、Javaのこれらのメソッドはすべて、コンパイル時と実行時の両方で使用できます。
いいえ。さらに、ジェネリック型はコンパイラによって上限まで消去されるため、実行時にジェネリック型 T の新しいインスタンスを作成することはできません。
Java でメタプログラミングを行う最善の方法は、型消去を回避し、Class<T>
型 T のオブジェクトを渡すことです。それでも、これはハックにすぎません。
Java 用の強力なコンパイル時ロジックが必要な場合、それを行う 1 つの方法は、ある種のコード生成を使用することです。他の投稿者が指摘しているように、Java 言語はコンパイル時のロジックを実行するのに適した機能を提供していないため、これが最良の選択肢かもしれません (コンパイル時のロジックが本当に必要な場合)。他の可能性を使い果たし、コード生成を行いたいと確信したら、私のオープン ソース プロジェクト Rjava に興味があるかもしれません。
http://www.github.com/blak3mill3r
これは、Ruby on Rails アプリケーション用の Google Web Toolkit インターフェースを自動的に生成するために作成した、Ruby で記述された Java コード生成ライブラリーです。そのためには非常に便利であることが証明されています。
警告として、Rjava コードをデバッグするのは非常に難しい場合があります。Rjava は多くのチェックを行いません。ユーザーが何をしているのかを理解していることを前提としています。とにかく、それはほとんど静的メタプログラミングの状態です。C++ TMP で行う重要な作業よりもデバッグがはるかに簡単であり、同じ種類のものに使用することができます。
いずれにしても、Java ソース コードを出力するプログラムを作成することを検討している場合は、今すぐやめて Rjava を調べてください。まだご希望の機能にはならないかもしれませんが、MIT のライセンスを受けているので、自由に改良したり、揚げ物にしたり、おばあちゃんに売ったりしてください。ジェネリック プログラミングの経験がある他の開発者が設計についてコメントしてくれることを嬉しく思います。
いいえ、Java のジェネリックは純粋にオブジェクトのキャストを回避する方法です。