const val 能做什么而 @JvmField val 不能?

Dwi*_* Ji 5 kotlin

领英问题

const val 能做什么而@JvmFieldval 不能做什么?

关于 Val 和 const 之间的区别有多种答案。Canst Val 和 Val 有什么区别@JvmField

Jof*_*rey 6

我不确定这种混乱是如何产生的,但这两个概念并没有真正相关。const val是关于声明编译时常量,而是@JvmField关于将属性公开为字段而不是通过 getters/setters。

什么可以const val做而 @JvmField val 不能做?

1 -const val使编译器在所有使用站点中内联常量的值。常量的用法在字节码中甚至不可见,只有常量的值存在。

这有一个重要的后果:如果模块 A 使用const val在模块 B 中声明的 a,并且该常量的值后来在模块 B 中更改,则需要针对模块 B 的新版本重新编译模块 A 才能看到更改。否则,即使新模块 B 位于类路径上,A 仍将使用旧的常量值。

2 -const val是一个平台无关的概念,它也可以在JS或Native平台上使用,而不仅仅是在JVM上。@JvmField是一个JVM概念。

其他值得注意的差异:

  • const val只能在顶层或objects中使用,而@JvmField可以在任何属性上使用。
  • 由于编译时内联,const val只能包含基本类型或 String 的值,并且初始化表达式必须足够简单以便在编译时计算。

仅供参考,该@JvmField注释用于 Kotlin 属性,将它们公开为字段,而不是通常的属性 getter/setter 约定。

以下 Kotlin 代码:

class A {
    val prop: Int = 42
}
Run Code Online (Sandbox Code Playgroud)

编译为与以下 Java 代码等效的字节码:

public final class A {
    private final int prop = 42;

    public int getProp() {
        return this.prop;
    }
}
Run Code Online (Sandbox Code Playgroud)

而使用@JvmField注解时,该字段将直接公开,无需 getter:

public final class A {
    public final int prop = 42;
}
Run Code Online (Sandbox Code Playgroud)

与 with 不同const val,编译器不会内联带@JvmField注释的属性的值。该属性甚至不必是val- 您可以有一个 -@JvmField带注释的var属性,这绝对不是常量。