Die @JvmSynthetic-Anmerkung in Kotlin

Die @ JvmSynthetic Annotation in Kotlin

1. Einführung

Kotlin is a programming language for the JVM and compiles directly to Java Bytecode. Es ist jedoch viel prägnanter als Java und bestimmte JVM-Funktionen passen nicht direkt in die Sprache.

StattdessenKotlin provides a set of annotations that we can apply to our code to trigger these features. Diese sind alle im Paketkotlin.jvm innerhalb vonkotlin-stdlib vorhanden.

Eine der esoterischeren ist die Annotation von@JvmSynthetic.

2. Was macht@JvmSynthetic?

Diese Anmerkung gilt für Methoden, Felder, Getter und Setter - und siemarks the appropriate element as synthetic in the generated class file.

Wir können diese Annotation in unserem Code genauso verwenden wie jede andere Annotation:

@JvmSynthetic
val syntheticField: String = "Field"

var syntheticAccessor: String
  @JvmSynthetic
  get() = "Accessor"

  @JvmSynthetic
  set(value) {
  }

@JvmSynthetic
fun syntheticMethod() {
}

Wenn der obige Code kompiliert wird,the compiler assigns the ACC_SYNTHETIC attribute to the corresponding elements in the class file:

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/example/kotlin/SyntheticTest;
    LineNumberTable:
      line 20: 0

3. Was ist das synthetische Attribut?

The ACC_SYNTHETIC attribute is intended by the JVM Bytecode to indicate that an element wasn’t actually present in the original source code, wurde aber stattdessen vom Compiler generiert.

Die ursprüngliche Absicht bestand darin, verschachtelte Klassen und Schnittstellen in Java 1.1 zu unterstützen, aber jetzt können wir sie auf alle Elemente anwenden, für die wir sie möglicherweise benötigen.

Any element that the compiler marks as synthetic will be inaccessible from the Java language. Dies beinhaltet, dass Sie in keinem Tool wie unserer IDE sichtbar sind. Unser Kotlin-Code unterliegt jedoch keinen derartigen Einschränkungen und kann diese Elemente problemlos anzeigen und darauf zugreifen.

Beachten Sie, dass, wenn wir ein Kotlin-Feld haben, das mit@JvmSynthetic, aber nicht mit@JvmField, kommentiert ist, der generierte Getter und Setter nicht als synthetische Methoden betrachtet werden und auf die problemlos zugegriffen werden kann.

Wir können über die Reflection-API von Java aus auf synthetische Elemente zugreifen, wenn wir sie finden können - zum Beispiel nach Namen:

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

4. Wofür kann ich das verwenden?

Die einzigen wirklichen Vorteile sind das Verbergen von Code vor Java-Entwicklern und -Tools sowie ein Hinweis für andere Entwickler auf den Status des Codes. It’s intended for working at a much lower level than most typical application code.

The intention of it is to support code generation, sodass der Compiler Felder und Methoden generieren kann, die anderen Entwicklern nicht zugänglich gemacht werden sollten, aber zur Unterstützung der tatsächlich offengelegten Schnittstelle erforderlich sind. Wir können es uns als ein Schutzniveau vorstellen, das überprivate oderinternal hinausgeht.

Alternativ können wir damit Code vor anderen Tools, verbergen, z. B. vor Codeabdeckung oder statischer Analyse.

Es gibt jedoch keine Garantie dafür, dass ein bestimmtes Tool diese Flagge anerkennt, sodass es hier möglicherweise nicht immer nützlich ist.

5. Fazit

Die Annotation@JvmSyntheticist möglicherweise nicht das nützlichste verfügbare Tool, kann jedoch in bestimmten Situationen verwendet werden, wie wir hier gesehen haben.

Wie immer kann ein anderes in Ihrer Entwickler-Toolbox verfügbares Tool von großem Nutzen sein, auch wenn wir es möglicherweise nur selten verwenden. Wenn Sie dieses Tool benötigen, sollten Sie wissen, wie es funktioniert.