1前書き

  • KotlinはJVM用のプログラミング言語で、Java Bytecode ** に直接コンパイルされます。ただし、これは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フィールドがある場合、生成されたgetterおよびsetterは合成メソッドとは見なされず、正しくアクセスできます。

名前から検索できる場合は、Reflection APIを使用してJavaから合成要素にアクセスできます。

Method syntheticMethod = SyntheticClass.class.getMethod("syntheticMethod");
syntheticMethod.invoke(syntheticClass);


4これを何に使用できますか?

これの唯一の本当の利点は、Java開発者やツールからコードを隠すこと、そしてコードの状態に関して他の開発者への指標としてです。

これは、最も一般的なアプリケーションコード

よりもはるかに低いレベルで作業するためのものです。

これは、コード生成をサポートすることを目的としており、他の開発者には公開されるべきではないが実際に公開されているインターフェースをサポートするために必要なフィールドとメソッドをコンパイラが生成できるようにします。私たちはそれを「個人の保護」や「内部の保護」を超えた保護のレベルと考えることができます。

あるいは、コードカバレッジや静的分析などの他のツールからコードを隠すためにそれを使用することができます。

ただし、特定のツールがこのフラグを尊重することを保証するものではないため、ここで常に役立つとは限りません。


5結論


@ JvmSynthetic

アノテーションは、利用可能な最も便利なツールではないかもしれませんが、ここで見たように、特定の状況では用途があります。

いつものように、私たちはめったにそれを使わないかもしれませんが、あなたの開発者ツールボックスで利用可能な別のツールは非常に有益でありえます。あなたがこのツールを必要としている時が来たら、それがどのように機能するのか知っておく価値があります。