Kotlin中const关键字的使用意义?已明确val与const val的区别
嘿,这个问题问得很有意思——虽然从生成的Java代码看两者好像没差,但Kotlin里const关键字的价值其实藏在编译过程和语义层面里,咱们慢慢拆解:
首先看你给出的代码示例:
Kotlin代码
class Application private val testVal = "example" private const val testConst = "another example"
生成的Java代码
public final class ApplicationKt { private static final String testVal = "example"; private static final String testConst = "another example"; }
确实,生成的字节码看起来几乎一模一样,但背后的逻辑有本质区别:
编译期常量 vs 运行期初始化
const val是编译期常量,它的值在编译阶段就被完全确定,当其他代码引用它时,编译器会直接把它替换成对应的字面量(比如你在别的地方用testConst,编译后就变成了"another example")。而普通的val(哪怕是顶层或伴生对象里的)是在类初始化的运行时阶段才被赋值的,引用它的时候会触发一次静态字段的访问操作。语义明确性与使用限制
const val有严格的使用限制:只能是基本类型、String,且必须定义在顶层或者伴生对象中。这种限制其实是在给编译器和其他开发者传递明确的信号:这是一个绝对不变、没有任何计算逻辑的常量,不能用函数调用或者动态表达式初始化(比如const val x = getValue()会直接编译报错)。而普通val只是“只读变量”,可以是任意类型,也能通过复杂逻辑初始化,语义上的约束弱很多。特殊场景的硬性要求
最关键的一点:const val可以用于注解的参数,而普通val不行。因为注解的参数必须是编译期就能确定的值,比如Kotlin标准库里的@JvmStatic、@Target这些注解里的参数,全都是const val定义的常量。如果用普通val作为注解参数,编译器会直接报错。微小但存在的性能优化
因为const val是直接嵌入字面量,运行时不需要去访问类的静态字段,能减少一次字段读取的开销——虽然单个场景下差异很小,但在高频调用的代码路径里,这种累积的优化还是有意义的。
内容的提问来源于stack exchange,提问作者Marek J

