インタフェースClassFileTransform<C extends ClassFileTransform<C,E,B>, E extends ClassFileElement, B extends ClassFileBuilder<E,B>>
- 型パラメータ:
C
- 変換タイプE
- メンバー要素タイプB
- ビルダー・タイプ
- 既知のすべてのサブインタフェース:
ClassTransform
,CodeTransform
,FieldTransform
,MethodTransform
CompoundElement
の個々のメンバー要素を処理し、結果をClassFileBuilder.transform(java.lang.classfile.CompoundElement<E>, java.lang.classfile.ClassFileTransform<?, E, B>)
を介してClassFileBuilder
に送信する変換。 ClassFileTransform
のサブタイプは、次のシール済クラス階層に示すように、CompoundElement
およびClassFileBuilder
の各サブタイプに対して定義されます。
たとえば、CodeModel
の基本的な変換では、Foo
クラスの静的メソッドへのすべてのコールを Bar
クラスにリダイレクトし、他のすべての要素を保持します:
CodeTransform fooToBar = (b, e) -> {
if (e instanceof InvokeInstruction i
&& i.owner().name().equalsString("Foo")
&& i.opcode() == Opcode.INVOKESTATIC) {
// remove the old element i by doing nothing to the builder
// add a new invokestatic instruction to the builder
b.invokestatic(CD_Bar, i.name().stringValue(), i.typeSymbol(), i.isInterface());
} else {
b.with(e); // leaves the element in place
}
};
builder::with
に提示する必要があります。 アクションが実行されない場合、そのメンバー要素は削除されます。
変換のより高度な使用方法には、以前に検出されたメンバー要素に基づいてディシジョンを行う「開始または終了の処理」、「ステートフル変換」、および1つの変換が入力複合構造に対する前の変換の結果を処理する変換の「組成」があります。 これらの機能はすべて、このインタフェースでサポートされており、ユーザー変換の実装からアクセスできます。
ユーザーは、atStart(B)
およびatEnd(B)
をオーバーライドして、変換のカスタムの開始および終了処理を定義できます。 開始ハンドラは、メンバー要素が処理される前に呼び出され、すべてのメンバー要素が処理された後に終了ハンドラが呼び出されます。 たとえば、開始ハンドラはコード配列の先頭に余分なコード要素を注入するために使用でき、終了ハンドラはステートフル変換と組み合せて、属性がマージされたかどうかを判断したり、新しい属性を定義する必要があるかどうかを判断するなど、クリーンアップ・アクションを実行できます。 ClassFileTransform
の各サブタイプは、終了処理のみを持つ変換を戻すユーティリティ・メソッドendHandler
を定義します。
変換には、個々のメンバー・エレメントの処理中に保持される状態を含めることができます。 たとえば、変換が注釈を注入する場合、変換が検出され、更新されたRuntimeVisibleAnnotationsAttribute
がビルダーに提示されていれば、その変換は追跡し続けます。まだ提供されていない場合は、挿入された注釈のみを含む新しい属性をエンド・ハンドラに表示できます。 このような変換を共有または再利用する場合は、戻される各変換に独自の状態が必要です。 ClassFileTransform
の各サブタイプは、ユーティリティ・メソッドofStateful
を定義します。このユーティリティ・メソッドでは、変換が再使用されるたびに、サプライヤが初期状態で変換を作成します。
変換は、andThen(C)
で構成できます。 この変換が別の変換で構成される場合、ClassFileBuilder
によって受信される出力メンバー要素がその他の変換への入力要素になることを意味します。 コンポジションでは、複数の変換を実行するための中間構造の構築が回避されます。 ClassFileTransform
の各サブタイプにはandThen(C)
が実装されており、通常はユーザーが実装することはできません。
小さい構造上で実行される変換は、その包含構造体に持ち上げて、同じ種類の囲まれた小さな構造すべてに対して選択的に実行できます。 たとえば、ClassTransform.transformingMethodBodies(Predicate, CodeTransform)
を介してCodeTransform
を持ち上げて、実行されているクラス内のselectメソッドのメソッド本文を変換できます。 これにより、ユーザーは小さな変換を記述し、より大きなスケールに適用できます。
ClassFileBuilder.transform(java.lang.classfile.CompoundElement<E>, java.lang.classfile.ClassFileTransform<?, E, B>)
の他に、ClassFile.transformClass(java.lang.classfile.ClassModel, java.lang.classfile.ClassTransform)
、ClassBuilder.transformField(java.lang.classfile.FieldModel, java.lang.classfile.FieldTransform)
、ClassBuilder.transformMethod(java.lang.classfile.MethodModel, java.lang.classfile.MethodTransform)
、MethodBuilder.transformCode(java.lang.classfile.CodeModel, java.lang.classfile.CodeTransform)
など、変換を便利に受け入れる他のメソッドもあります。 これらは、変換シナリオの大部分に適合するコンビニエンス・メソッドです。
-
メソッドのサマリー
-
メソッドの詳細
-
accept
ビルダーで適切なアクションを実行して、要素を変換します。 クラス・ファイル・エンティティ(クラス、メソッド、フィールド、メソッド本文。)の変換時に使用されます。 変換が不要な場合は、ClassFileBuilder.with(ClassFileElement)
に要素を表示できます。 要素を削除する場合、アクションは必要ありません。このメソッドは、Class-File APIによってコールされます。 ユーザーは、このメソッドをコールしないでください。
- パラメータ:
builder
- 新しいエンティティのビルダーelement
- 要素
-
atEnd
default void atEnd(B builder) クラス・ファイル・エンティティの変換中に、最終的なアクションを実行します。 クラスのすべての要素がaccept(ClassFileBuilder, ClassFileElement)
に提示された後に呼び出されます。このメソッドは、Class-File APIによってコールされます。 ユーザーは、このメソッドをコールしないでください。
- 実装要件:
- デフォルト実装は何も実行しません。
- パラメータ:
builder
- 新しいエンティティのビルダー
-
atStart
default void atStart(B builder) クラス・ファイル・エンティティの変換中に、事前アクションを実行します。 クラスの要素がaccept(ClassFileBuilder, ClassFileElement)
に提示される前に呼び出されます。このメソッドは、Class-File APIによってコールされます。 ユーザーは、このメソッドをコールしないでください。
- 実装要件:
- デフォルト実装は何も実行しません。
- パラメータ:
builder
- 新しいエンティティのビルダー
-
andThen
-