在 Kotlin 编程中,constvarval 是非常基础且重要的关键字,它们分别用于声明不同类型的变量。理解它们之间的区别,有助于写出更安全、更清晰的代码。

本文将从变量的可变性、编译时常量、以及 Java 对应写法等多个角度来对比这三个关键字,帮助你更好地掌握它们的使用场景和注意事项。


1. Kotlin 类型系统概述

在深入探讨 varvalconst 之前,我们先来了解 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. 结语

掌握 varvalconst 的区别是 Kotlin 编程的基础。合理使用它们可以提升代码的可读性、可维护性以及运行效率。希望本文能帮助你更好地区分它们的使用场景和注意事项。


原始标题:Kotlin const, var, and val Keywords