Статические переменные в Котлине по-прежнему являются частью экземпляров объектов

Как известно, для объявления переменной static мы должны использовать companion object .

Ниже приведен простой пример.

 class MainActivity : AppCompatActivity() { companion object { val extraMessage = "message" } } 

К этому можно обратиться в Other Activity as MainActivity.extraMessage , довольно аккуратно и просто.

Однако в документе говорится, что синтаксис выглядит как его статический, но во время выполнения они все еще являются членами экземпляра реального объекта.

Точно так же, как у Котлина нет статических членов, а Котлин просто предоставил более простой способ написать код.

В intelliJ вы можете подключить плагин kotlin для декомпиляции сгенерированного байт-кода, чтобы вы могли видеть, что происходит. Ваш код генерирует приближение следующего кода:

 import kotlin.Metadata; import kotlin.jvm.internal.DefaultConstructorMarker; import org.jetbrains.annotations.NotNull; import android.support.v7.app.AppCompatActivity; @Metadata( mv = {1, 1, 7}, bv = {1, 0, 2}, k = 1, d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"}, d2 = {"LMainActivity;", "Landroid/support/v7/app/AppCompatActivity;", "()V", "Companion", "special module for files not under source root"} ) public final class MainActivity extends AppCompatActivity { @NotNull private static final String extraMessage = "message"; public static final MainActivity.Companion Companion = new MainActivity.Companion((DefaultConstructorMarker)null); @Metadata( mv = {1, 1, 7}, bv = {1, 0, 2}, k = 1, d1 = {"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0003\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002R\u0014\u0010\u0003\u001a\u00020\u0004X\u0086D¢\u0006\b\n\u0000\u001a\u0004\b\u0005\u0010\u0006¨\u0006\u0007"}, d2 = {"LMainActivity$Companion;", "", "()V", "extraMessage", "", "getExtraMessage", "()Ljava/lang/String;", "special module for files not under source root"} ) public static final class Companion { @NotNull public final String getExtraMessage() { return MainActivity.extraMessage; } private Companion() { } // $FF: synthetic method public Companion(DefaultConstructorMarker $constructor_marker) { this(); } } } 

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

Этот код:

 class MainActivity { companion object { val extraMessage = "message" } } 

дает этот java-код, когда файл класса декомпилируется (используя http://www.javadecompilers.com/ ):

 import kotlin.Metadata; public final class MainActivity { public static final MainActivity.Companion Companion = new MainActivity.Companion(null); private static final String extraMessage = "message"; public MainActivity() {} } 

Как показано на рисунке, extraMessage хранится как статическое поле сгенерированного класса, а Kotlin позволяет получить доступ к полю так же, как и в Java.