Kotlin中的静态数据

Let*_*far 27 kotlin

请告诉我,这个例子中是否存在任何差异(就Java而言):

  1. object DefaultValues {
        val FILES_TO_DOWNLOAD = 100
    }
    
    Run Code Online (Sandbox Code Playgroud)

    class DefaultValues {
        companion object {
            val FILES_TO_DOWNLOAD = 100
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 没有类或对象包装器:

    const val DEFAULT_FILES_TO_DOWNLOAD = 100
    
    Run Code Online (Sandbox Code Playgroud)

    val DEFAULT_FILES_TO_DOWNLOAD = 100
    
    Run Code Online (Sandbox Code Playgroud)

定义的真正方法是什么?:

public static final int FILES_TO_DOWNLOAD = 100
Run Code Online (Sandbox Code Playgroud)

hot*_*key 26

您可以使用Kotlin字节码查看器来查找这些选项的编译内容.

使用Kotlin 1.0.2编译的字节码显示出来

  1. val属性objectcompanion object编译到private static final类中的字段:

     // access flags 0x1A
     private final static I FILES_TO_DOWNLOAD = 100
    
    Run Code Online (Sandbox Code Playgroud)

    和一个getter,在引用属性时调用:

     // access flags 0x1019
     public final static synthetic access$getFILES_TO_DOWNLOAD$cp()I
    
    Run Code Online (Sandbox Code Playgroud)

    从Java,吸气剂可以被称为DefaultValues.INSTANCE.getFILES_TO_DOWNLOAD()DefaultValues.Companion.getFILES_TO_DOWNLOAD()分别.

  2. const顶级属性被编译为与(1)相同,只是区别于现在将字段和getter放在FilenameKt类中.

    但顶级const val编译成一个public static final字段:

    // access flags 0x19
    public final static I DEFAULT_FILES_TO_DOWNLOAD = 100
    
    Run Code Online (Sandbox Code Playgroud)

    当a const val在对象内声明时,将产生相同的公共静态最终字段.此外,如果@JvmField(1)中声明的属性添加注释,则可以获得相同的结果字节码.


得出的结论是,你可以定义public static final使用领域const@JvmField无论是在一个object或顶层.

  • @ LouisCAD,const val和@JvmField比简单的val更有效,但这主要是由于getter调用,而JVM非常擅长内联函数,尤其是在运行时内插。我想从长远来看,性能差异应该可以忽略不计(对于代码的非关键部分)。至于字节码的大小,第二个选项也会产生较小的字节码,但是无论如何,您不太可能节省很多优化。 (2认同)