1

メソッドの呼び出しやフィールドの値の変更など、Reflection を使用すると便利なことができることはわかっています。ただし、実行時およびプログラムでより重いコード変更を行うことは可能ですか?

たとえば、メソッドがある場合:

public void foo(){
    this.bar = 100;
}

このメソッドの内部を変更し、フィールドに定数が割り当てられていることに気づき、それを次のように変更するプログラムを作成できますか?

public int baz = 100;

public void foo(){
    this.bar = baz;
}

おそらくJavaは、この種のことを行う言語ではないかもしれません-そうでない場合、基本的にこの方法でコードを再解析または検査し、それを非常に正確に変更できる言語の提案を受け入れます. 私はここで夢物語かもしれませんが、これも当てはまるかどうか教えてください.

4

5 に答える 5

0

友人からの提案を追加するだけです - Apache Commons の BCEL は素晴らしく見えます:

http://commons.apache.org/bcel/manual.html

Byte Code Engineering Library (Apache Commons BCEL™) は、(バイナリ) Java クラス ファイル (.class で終わるもの) を分析、作成、および操作するための便利な方法をユーザーに提供することを目的としています。クラスは、特定のクラスのすべてのシンボリック情報 (特に、メソッド、フィールド、およびバイトコード命令) を含むオブジェクトによって表されます。このようなオブジェクトは、既存のファイルから読み取ることができ、プログラム (実行時のクラスローダーなど) によって変換され、再びファイルに書き込まれます。さらに興味深いアプリケーションは、実行時にゼロからクラスを作成することです。Java 仮想マシン (JVM) と Java .class ファイルの形式について知りたい場合は、Byte Code Engineering Library (BCEL) も役立つ場合があります。

于 2012-11-30T14:41:10.547 に答える
0

こんな感じですか?

String script1 = "println(\"OK!\");";
eval( script1 );
script1 += "println(\"... well, maybe NOT OK after all\");";
eval( script2 );

出力:

OK!
OK!
... well, maybe NOT OK after all

... Java のスクリプト拡張機能を使用します。Groovy などを使用すると、おそらくやりたいことを実行できるようになります。私は、リフレクションを介して Java とほぼシームレスに統合するスクリプト拡張機能を作成しました。詳細に興味がある場合は、私に連絡してください。

于 2012-12-12T02:16:36.110 に答える
0

ソースレベルで言語を解析および変換するための一般的な機能を提供するプログラム変換システム (PTS)を調査したいと考えています。PTS は、ターゲット言語の表面構文を使用して、「このパターンが表示されたら、そのパターンに置き換えてください」という事実上の書き換えルールを提供します。これは完全なパーサーを使用して行われるため、書き換えルールは実際にはテキストではなく言語構文で機能します。そのような書き換えルールは、正規表現に基づくツールとは異なり、コメント内のコードのようなテキストを変更しようとしないことは明らかです。

当社の DMS ソフトウェア リエンジニアリング ツールキットはその 1 つです。通常の構文解析、AST の構築、prettyprinting (コメントを含むコンパイル可能なソース コードの再生成) を提供するだけでなく、シンボル テーブルと制御およびデータ フローの分析もサポートします。これらは、ほとんどすべての興味深い変換に必要です。DMS には、Java のさまざまな方言や他の多くの言語のフロント エンドもあります。

バイトコード トランスフォーマーが存在するのは、ビルドがはるかに簡単だからです。バイトコードを「解析」するのはとても簡単です。もちろん、バイトコード トランスフォーマーを使用して永続的なソース変更を行うことはできないため、あまり役に立ちません。

于 2012-12-12T03:28:05.013 に答える
0

バイトコード操作を可能にするソフトウェアを探しています。これを実現するためのフレームワークはいくつかありますが、現在最もよく知られているのは次の 2 つです。

Java クラスで実行時にバイトコードの変更を行う場合は、次の点に注意してください。

  • クラスローダによってクラスがロードされた後にクラスのバイトコードを変更する場合は、そのクラス定義を再ロードする方法を見つける必要があります (クラスロードのトリックまたはホットスワップ機能を使用して)。

  • クラス インターフェイスを変更すると (新しいメソッドやフィールドを追加するなど)、リフレクションを介してしかアクセスできなくなります。

于 2012-11-30T14:43:34.347 に答える
0

Java はこの目的を念頭に置いて設計されていなかったと言っても過言ではありませんが、可能性はあります。どのように、いつ行うかは、エクササイズの最終的な目的によって異なります。いくつかのオプション:

  • ソース コード レベルでは、Java コンパイラ APIを使用して、任意のコードをクラス ファイルにコンパイルできます (後でロードできます)。

  • バイトコード レベルでは、 ClassFileTransformerをインストールするエージェントを記述して 、クラスがロードされるときに「その場で」クラスを任意に変更できます。実際には、これを行う場合、クラスの操作を容易にするためにBCEL (Bytecode Engineering Library)などのライブラリも使用することになるでしょう。

于 2012-11-30T14:49:23.470 に答える