バイトコード操作にはどのような正当な用途があり、それらのバイトコード操作ベースのソリューションを実際に実装する方法は?
更新:この質問は、実際には、バイトコード操作の助けを借りてコードを飛ばすために人々が使用するパターンとテクニックに関するものであることをもっと明確にする必要がありました。
すでに言及されているアスペクト指向プログラミングや、その場でのプロキシ オブジェクトの構築、および同様の手法のようなものです。
バイトコード操作にはどのような正当な用途があり、それらのバイトコード操作ベースのソリューションを実際に実装する方法は?
更新:この質問は、実際には、バイトコード操作の助けを借りてコードを飛ばすために人々が使用するパターンとテクニックに関するものであることをもっと明確にする必要がありました。
すでに言及されているアスペクト指向プログラミングや、その場でのプロキシ オブジェクトの構築、および同様の手法のようなものです。
バイトコード操作により、次のような複雑な (そして興味深い) プログラム変換を任意に実装できます。
範囲は無限です。これはほんの小さなサンプルです。
これが通常どのように行われるかについては、ここから始めてください。
したがって、バイトコードを読み取ってインタープリター / JVM を実装できます。Java コンパイラまたは JVM をターゲットとする別の言語 ( ScalaやJythonなど) のコンパイラを実装するときに、バイトコードを記述/生成できます。バイトコードを最適化するためにバイトコード操作を実行する場合があります (バイトコード オプティマイザーを作成して販売する場合、または会社のコードに競争力を与えるための内部ツールとしてそれが必要な場合)。同様に、配布前に難読化するためにバイトコードを操作することもできます。アスペクト指向プログラミングのバイトコード操作を実行することもできます; たとえば、フックを挿入したい場合 (おそらくタイミングやログの目的、またはその他の理由で)、すべてのソース ファイルを編集するよりもバイトコードを操作する方が簡単または安価である場合 (たとえば、ソースコードが利用できないか、多くの異なるソースからのものであり、そのすべてが管理下にあるわけではないか、チームにそのようなフックを追加するよう説得するには費用と時間がかかる可能性があります)。元のコードを変更しようとするのではなく、最終的なバイトコード出力に変更を挿入することを意味します (アップストリームまたは別のフォークを維持するか、バイトコードのみを提供するサードパーティからソースコードを購入する必要がある場合があります)。
バイトコードを自分で操作することはできますが、BCELやASMなど、既存のオープン ソース ライブラリやフレームワークが数多く存在します。
アスペクト指向設計のパターン(PDF) およびアスペクト指向設計の原則: オブジェクト指向設計からの教訓(PDF)という論文があり、AOP/バイトコード操作のいくつかのパターンについて説明しています。
個人的には、1 つのフレームワークでASMを使用したバイトコード操作を使用して、そのフレームワークを使用するクラスのボイラープレート コードを生成しました。フレームワークには、クライアント コード用のカスタム equals() および hashCode() メソッドが必要なので、ClassLoader がクラスをロードするときにバイトコードを変更するJava Agentにフックすることで、これらを生成します。また、 CGLIBを使用して動的プロキシを生成することも何度もありました (それが AOP と見なされる場合)。
バイトコード操作の用途の 1 つは、アスペクト指向プログラミングです。Java では、これにAspectJを使用できます。
BEA KODO (Implementation of the Java Data Objects specification) などの一部のフレームワークは、バイトコード操作を使用して Plain Old Java Objects を「拡張」し、XML 記述に基づいて永続化ロジックを追加します。
したがって、データベース マッピング情報はバイトコード上で自動的に生成されます。