Аннотация @JvmSynthetic в Kotlin

1. Введение

Kotlin - это язык программирования для JVM, который компилируется непосредственно в байт-код Java. Однако он намного более лаконичен, чем Java, и некоторые функции JVM напрямую не вписываются в язык.

Вместо этого
Kotlin предоставляет набор аннотаций, которые мы можем применить к нашему коду для запуска этих функций. Все это существует в пакете kotlin.jvm в kotlin-stdlib.

Одной из наиболее эзотерических из них является аннотация @JvmSynthetic.

1. Введение  Kotlin - это язык программирования для JVM, который компилируется непосредственно в байт-код Java.

2. Что делает @JvmSynthetic?

Эта аннотация применима к методам, полям, получателям и установщикам, и она помечает соответствующий элемент как синтетический в сгенерированном файле класса.

Мы можем использовать эту аннотацию в нашем коде точно так же, как и любую другую аннотацию:

@JvmSynthetic
val syntheticField: String = "Field"

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

@JvmSynthetic
set(value) {
}

@JvmSynthetic
fun syntheticMethod() {
}

Когда приведенный выше код скомпилирован, компилятор присваивает атрибут ACC_SYNTHETIC соответствующим элементам в файле class:

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 не имеет таких ограничений и может прекрасно видеть эти элементы и получать к ним доступ.

Обратите внимание, что если у нас есть поле Kotlin, помеченное @JvmSynthetic, но не помеченное @JvmField, то сгенерированные getter и setter не считаются синтетическими методами и могут быть доступны без проблем.

Мы можем получить доступ к синтетическим элементам из Java с помощью Reflection API, если сможем найти их — например, по имени:

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

4. Для Чего Я Могу Это Использовать?

Единственными реальными преимуществами этого являются скрытие кода от Java-разработчиков и инструментов, а также информирование других разработчиков о состоянии кода. Он предназначен для работы на гораздо более низком уровне, чем код большинства обычных приложений.

Целью этого является поддержка генерации кода, позволяющая компилятору генерировать поля и методы, которые не должны быть доступны другим разработчикам, но которые необходимы для поддержки фактического открытого интерфейса. Мы можем рассматривать это как уровень защиты, выходящий за рамки частного или внутреннего.

В качестве альтернативы мы можем использовать его для скрытия кода от других инструментов, таких как code coverage или статический анализ.

Однако нет гарантии, что какой-либо данный инструмент будет использовать этот флаг, поэтому он не всегда может быть полезен в данном случае.

5. Заключение

Аннотация @JvmSynthetic, возможно, и не самый полезный инструмент из доступных, но, как мы уже видели, в определенных ситуациях он пригодится.

Как всегда, даже если мы используем его крайне редко, другой инструмент, доступный в вашем наборе инструментов разработчика, может оказаться весьма полезным. Когда придет время, когда у вас возникнет потребность в этом инструменте, стоит узнать, как он работает.

Оригинал статьи: https://www.baeldung.com/kotlin/jvm-synthetic