Kotlinの@JvmSyntheticアノテーション
1. 序章
KotlinはJVMのプログラミング言語であり、Javaバイトコードに直接コンパイルされます。 ただし、Javaよりもはるかに簡潔であり、特定のJVM機能は言語に直接適合しません。
代わりに、 Kotlinは、これらの機能をトリガーするためにコードに適用できる一連のアノテーションを提供します。 これらはすべて、kotlin-stdlib内のkotlin.jvmパッケージに含まれています。
これらの中で最も難解なものの1つは、@JvmSyntheticアノテーションです。
2. @JvmSynthetic は何をしますか?
このアノテーションは、メソッド、フィールド、ゲッター、およびセッターに適用できます。は、生成されたクラスファイルで適切な要素を合成としてマークします。
このアノテーションは、他のアノテーションとまったく同じようにコードで使用できます。
@JvmSynthetic
val syntheticField: String = "Field"
var syntheticAccessor: String
@JvmSynthetic
get() = "Accessor"
@JvmSynthetic
set(value) {
}
@JvmSynthetic
fun syntheticMethod() {
}
上記のコードがコンパイルされると、コンパイラはACC_SYNTHETIC属性をクラスファイルの対応する要素に割り当てます。
private final java.lang.String syntheticField;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE, ACC_FINAL, ACC_SYNTHETIC
ConstantValue: String Field
RuntimeInvisibleAnnotations:
0: #9()
public final void syntheticMethod();
descriptor: ()V
flags: ACC_PUBLIC, ACC_FINAL, ACC_SYNTHETIC
Code:
stack=0, locals=1, args_size=1
0: return
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lcom/baeldung/kotlin/SyntheticTest;
LineNumberTable:
line 20: 0
3. 合成属性とは何ですか?
ACC_SYNTHETIC属性は、要素が元のソースコードに実際には存在せず、代わりにコンパイラによって生成されたことを示すために、JVMバイトコードによって意図されています。
当初の目的は、Java 1.1でネストされたクラスとインターフェースをサポートすることでしたが、今では、必要になる可能性のある任意の要素に適用できます。
コンパイラが合成としてマークする要素は、Java言語からアクセスできなくなります。 これには、IDEなどのツールに表示されないことも含まれます。 ただし、Kotlinコードにはそのような制限はなく、これらの要素を完全に表示してアクセスできます。
@JvmSynthetic で注釈が付けられているが、 @JvmField、で注釈が付けられていないKotlinフィールドがある場合、生成されたゲッターとセッターは合成メソッドとは見なされず、問題なくアクセスできます。
合成要素を見つけることができれば、Reflection APIを使用してJavaから合成要素にアクセスできます(たとえば、名前で)。
Method syntheticMethod = SyntheticClass.class.getMethod("syntheticMethod");
syntheticMethod.invoke(syntheticClass);
4. これは何に使用できますか?
これの唯一の本当の利点は、Java開発者とツールからコードを隠すことと、コードの状態に関する他の開発者への指標としてです。 これは、最も一般的なアプリケーションコードよりもはるかに低いレベルで動作することを目的としています。
コード生成をサポートし、コンパイラが他の開発者に公開されるべきではないが、実際に公開されたインターフェイスをサポートするために必要なフィールドとメソッドを生成できるようにすることを目的としています。 これは、プライベートまたは内部を超える保護レベルと考えることができます。
または、コードカバレッジや静的分析などの他のツール、からコードを非表示にするために使用することもできます。
ただし、特定のツールがこのフラグを尊重するという保証はないため、ここで常に役立つとは限りません。
5. 結論
@JvmSynthetic アノテーションは、利用可能な最も便利なツールではないかもしれませんが、ここで見たように、特定の状況で使用できます。
いつものように、私たちがそれを使用することはめったにないかもしれませんが、開発者ツールボックスで利用可能な別のツールは非常に有益です。 このツールが必要になったときは、それがどのように機能するかを知る価値があります。