Kotlin 中的静态变量是否仍然是实例对象的一部分



正如我们所知,要声明一个变量静态,我们必须使用companion object

下面列出了一个简单的示例。

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

这可以在其他活动中访问MainActivity.extraMessage,非常整洁和简单。

然而,文档指出,语法看起来像是静态的,但在运行时,它们仍然是真实对象的实例成员。

所以是 Kotlin 没有静态成员,还是 Kotlin 只是提供了一种更简单的代码编写方法。

在 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 = {"u0000fnu0002u0018u0002nu0002u0010u0000nu0002bu0003u0018u0000 u00032u00020u0001:u0001u0003Bu0005¢u0006u0002u0010u0002¨u0006u0004"},
   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 = {"u0000u0014nu0002u0018u0002nu0002u0010u0000nu0002bu0002nu0002u0010u000enu0002bu0003bu0086u0003u0018u00002u00020u0001Bu0007bu0002¢u0006u0002u0010u0002Ru0014u0010u0003u001au00020u0004Xu0086D¢u0006bnu0000u001au0004bu0005u0010u0006¨u0006u0007"},
      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 中一样访问该字段。

最新更新