在 Kotlin 编程中,const
、var
和 val
是非常基础且重要的关键字,它们分别用于声明不同类型的变量。理解它们之间的区别,有助于写出更安全、更清晰的代码。
本文将从变量的可变性、编译时常量、以及 Java 对应写法等多个角度来对比这三个关键字,帮助你更好地掌握它们的使用场景和注意事项。
1. Kotlin 类型系统概述
在深入探讨 var
、val
和 const
之前,我们先来了解 Kotlin 的类型系统。Kotlin 支持类型推断(inferred typing),这与 Java 的显式类型声明(manifest typing)形成对比。
1.1 显式类型(Manifest Typing)
在 Java 中,变量必须显式声明其类型。例如:
int myVariable = 3;
这种写法在 Java 中是必须的,类型信息必须明确写出。
1.2 类型推断(Inferred Typing)
而 Kotlin 支持类型推断,编译器会根据变量的初始值自动推断其类型:
val myVariable = 3
上面的例子中,虽然没有显式写出 Int
,但 Kotlin 编译器会自动将其推断为 Int
类型。这种机制让代码更加简洁,同时又不失类型安全性。
2. var:可变变量
var
是 Kotlin 中用于声明可变变量的关键字。一旦变量被声明为 var
,就可以在后续代码中更改其值。
示例:
var myVariable = 1
myVariable = 2
你也可以显式声明类型:
var myVariable: Int = 1
注意事项:
- 类型一旦确定后,就不能再赋值其他类型的数据 ❌
var myVariable: Int = 1 myVariable = "Hello" // 编译错误 ❌
3. val:只读变量
val
用于声明只读变量,即一旦赋值后就不能再更改。
示例:
val name = "Baeldung"
name = "New Name" // 编译错误 ❌
它类似于 Java 中使用 final
声明的变量:
final String name = "Baeldung";
初始化时机
val
变量可以在声明时赋值,也可以在构造函数中赋值(适用于类属性):
class Address(val street: String) {
val name: String = "Baeldung"
}
4. const:编译时常量
const
用于声明编译期已知的常量。它必须与 val
一起使用,并且只能用于顶层变量或对象声明中的属性。
示例:
const val WEBSITE_NAME = "Baeldung"
在 Java 中,这相当于:
final static String WEBSITE_NAME = "Baeldung";
4.1 常量内联(Constant Inlining)
从 Kotlin 1.1 开始,const val
的值会被内联到使用处,而不是作为静态字段访问。例如:
const val VALUE = "constant"
fun main() {
println("$VALUE is inlined")
}
编译后,VALUE
的值 "constant"
会被直接替换到使用位置,而不是通过静态字段获取。这提高了运行效率。
可以通过查看字节码验证这一点:
$ kotlinc Main.kt
$ javap -c -p -v MainKt
输出中会看到:
0: ldc #16 // String constant is inlined
说明字符串字面量直接被内联,没有调用 getstatic
获取静态字段。
✅ 总结:const val
看起来像静态字段,实际上只是编译器层面的优化,不是真正的 public static final
字段。
5. 总结与对比
关键字 | 可变性 | 是否编译时常量 | Java 类似写法 | 适用场景 |
---|---|---|---|---|
var |
✅ 可变 | ❌ 否 | 普通变量 | 需要修改值的变量 |
val |
❌ 只读 | ❌ 否 | final 变量 |
初始化后不变的变量 |
const val |
❌ 只读 | ✅ 是 | static final 常量 |
编译期已知的常量 |
6. 踩坑提醒
- ❌ 不要试图用
const
声明运行时才能确定的值,否则会编译失败。 - ❌
const
不能用于局部变量,只能用于顶层或对象声明。 - ⚠️ 使用
val
时,虽然变量不可变,但若变量是对象(如List
),则对象内部状态仍可能变化。
7. 结语
掌握 var
、val
和 const
的区别是 Kotlin 编程的基础。合理使用它们可以提升代码的可读性、可维护性以及运行效率。希望本文能帮助你更好地区分它们的使用场景和注意事项。