首页 > 解决方案 > const val 能做什么,@JvmField val 不能?

问题描述

领英问题

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

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

标签: kotlin

解决方案


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

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只能包含原始类型或字符串的值,并且初始化表达式必须足够简单以便在编译时进行评估。

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

以下 Kotlin 代码:

class A {
    val prop: Int = 42
}

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

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

    public int getProp() {
        return this.prop;
    }
}

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

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

与 with 不同const val,编译器不会内联@JvmField-annotated 属性的值。该属性甚至不必是val- 你可以有一个@JvmField-annotatedvar属性,这绝对不是一个常数。


推荐阅读