L’annotation @JvmSynthetic dans Kotlin

L'annotation @JvmSynthetic dans Kotlin

1. introduction

Kotlin is a programming language for the JVM and compiles directly to Java Bytecode. Cependant, il est beaucoup plus concis que Java et certaines fonctionnalités de JVM ne s’intègrent pas directement dans le langage.

Au lieu de cela,Kotlin provides a set of annotations that we can apply to our code to trigger these features. Ceux-ci existent tous dans le packagekotlin.jvm danskotlin-stdlib.

L’annotation@JvmSynthetic est l’une des plus ésotériques.

2. Que fait@JvmSynthetic?

Cette annotation est applicable aux méthodes, champs, getters et setters - et ilmarks the appropriate element as synthetic in the generated class file.

Nous pouvons utiliser cette annotation dans notre code exactement comme n'importe quelle autre annotation:

@JvmSynthetic
val syntheticField: String = "Field"

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

  @JvmSynthetic
  set(value) {
  }

@JvmSynthetic
fun syntheticMethod() {
}

Lorsque le code ci-dessus est compilé,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. Quel est l'attribut synthétique?

The ACC_SYNTHETIC attribute is intended by the JVM Bytecode to indicate that an element wasn’t actually present in the original source code, mais a été généré à la place par le compilateur.

Son objectif initial était de prendre en charge les classes et interfaces imbriquées dans Java 1.1, mais nous pouvons maintenant l'appliquer à tous les éléments pour lesquels nous pouvons en avoir besoin.

Any element that the compiler marks as synthetic will be inaccessible from the Java language. Cela inclut ne pas être visible dans aucun outillage, tel que notre IDE. Cependant, notre code Kotlin n’a pas de telles restrictions et peut parfaitement voir et accéder à ces éléments.

Notez que si nous avons un champ Kotlin annoté avec@JvmSynthetic mais pas annoté avec@JvmField, alors le getter et le setter générés ne sont pas considérés comme des méthodes synthétiques et peuvent être accédés très bien.

Nous pouvons accéder aux éléments synthétiques à partir de Java à l'aide de l'API Reflection si nous sommes en mesure de les localiser - par exemple, par leur nom:

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

4. À quoi puis-je l’utiliser?

Les seuls avantages réels de cette solution sont le fait de cacher du code aux développeurs et aux outils Java et d’indiquer à d’autres développeurs l’état du code. It’s intended for working at a much lower level than most typical application code.

The intention of it is to support code generation, permettant au compilateur de générer des champs et des méthodes qui ne devraient pas être exposés à d'autres développeurs, mais qui sont nécessaires pour prendre en charge l'interface exposée réelle. On peut le considérer comme un niveau de protection au-delà deprivate ouinternal.

Alternativement, nous pouvons l'utiliser pour masquer le code d'autres outils, tels que la couverture de code ou l'analyse statique.

Cependant, il n’ya aucune garantie qu’un outil donné respectera cet indicateur. Il n’est donc pas toujours utile ici.

5. Conclusion

L'annotation@JvmSynthetic n'est peut-être pas l'outil le plus utile disponible, mais elle a des utilisations dans certaines situations, comme nous l'avons vu ici.

Comme toujours, même si nous l’utilisons rarement, un autre outil disponible dans votre boîte à outils de développement peut être très bénéfique. Lorsque vous avez besoin de cet outil, il vaut la peine de savoir comment il fonctionne.