Kotlin:const val vs val

时间:2018-02-07 10:21:52

标签: android kotlin

我在Kotlin中理解const val用于声明常量,val用于只读属性。但是,我想知道以下情况,哪一个更适合使用。

假设我有一个片段,需要一个密钥才能用于saveInstanceStaterestoreInstanceState。我想知道以下两个选项中哪一个更好:

选项1:

class MyFragment {
    private val MY_KEY = "my_key"
    ...
}

选项2:

private const val MY_KEY = "my_key" // declared in the same file.

class MyFragment {
    ...
}

我更喜欢#option 2,因为它清楚地表明MY_KEY是一个常量,并且值是在编译时确定的。但是,由于它在顶层声明,因此需要在编译的java代码中创建一个类MyFragmentKt(假设文件名为MyFragment.kt)。在#option 1中,没有生成额外的类,虽然MY_KEY的值将在运行时分配而不是常量,但这在特定情况下的使用方式没有区别

所以虽然我个人更喜欢#option 2,但我的分析让我觉得#option 1并不差,如果不是更好的话。我只是想知道其他开发者如何看待这个问题,以及#option 2是否有任何其他好处,我还没有想到。感谢。

3 个答案:

答案 0 :(得分:16)

每次编写(非内联)lambda表达式时,都创建了另一个类。与此相比,创建一个用于保存顶级声明的类似乎很小。

此外,如果您在顶层的所有内容都是一个常量声明,它将被内联到每个使用站点(按规范),因此拥有类本身将变为未引用,因此可以通过ProGuard的最小化来定位。它很可能不会出现在您的制作APK中。

答案 1 :(得分:10)

这两个选项之间不仅存在语义差异。

选项1(类内val)是一个实例字段。

选项2(顶级const val)是顶级"静态"成员(大致,因为static在Kotlin中不存在。)

这就是生成MyFragmentKt类的原因:顶级成员被编译为名为[Filename]Kt的类。

我会考虑第三种选择:

class MyFragment {
    companion object {
        private const val MY_KEY = "my_key"
    }
}

这样,MY_KEY(来自Java)是static类的MyFragment成员,因为JvmStaticconst变量的推断。将生成Companion类(但它将为空)。

由于您的原始方法是课程中的一个字段,我觉得companion object / static常量可能更合适。

More about companion objects vs Java's static

答案 2 :(得分:-2)

我认为选项#2是正确的方式。