ZetCode

Kotlin const 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的 const 关键字用于声明编译时常量。这些常量必须在编译时已知,并且不能在运行时更改。本教程通过示例深入探讨了 const 关键字。

基本定义

Kotlin 中的 const 修饰符将属性标记为编译时常量。它只能应用于基本类型或 String 的不可变属性。常量必须在顶层或对象声明中声明。

顶层常量

声明常量的最常见位置是在文件的顶层。这些常量在整个文件中都可访问,并且可以导入到其他文件中。

TopLevelConstants.kt
package com.zetcode

const val PI = 3.1415926535
const val APP_NAME = "My Kotlin App"

fun main() {

    println("The value of PI is $PI")
    println("Welcome to $APP_NAME")
}

在这里,我们在文件的顶层声明了两个常量。它们可以在文件的任何地方使用,而无需类的实例。这些值在编译时已知,并且不能更改。

伴生对象中的常量

常量也可以在类的伴生对象中声明。这会将相关的常量与它们相关的类分组,同时保持编译时常量的属性。

CompanionConstants.kt
package com.zetcode

class MathUtils {

    companion object {
        const val E = 2.7182818284
        const val GOLDEN_RATIO = 1.6180339887
    }
}

fun main() {

    println("Euler's number: ${MathUtils.E}")
    println("Golden ratio: ${MathUtils.GOLDEN_RATIO}")
}

这些常量通过 MathUtils 类的伴生对象访问。当这些值与类密切相关时,这提供了比顶层常量更好的组织方式。这些值仍然是编译时常量。

常量 vs 常规 val

const val 和常规 val 之间的关键区别在于值的赋值时间。const val 必须在编译时已知,而 val 可以在运行时赋值。

ConstVsVal.kt
package com.zetcode

const val COMPILE_TIME_CONST = "Hello"
val runtimeVal = "World".uppercase()

fun main() {

    println("$COMPILE_TIME_CONST $runtimeVal")
}

COMPILE_TIME_CONST 在编译时已知,而 runtimeVal 在运行时计算。uppercase 调用阻止了 runtimeVal 成为编译时常量。两者都是不可变的,但在不同的时间初始化。

注解中的常量

常量通常用于注解,其中只允许编译时常量值。这确保了在编译代码时已知注解参数。

AnnotationConstants.kt
package com.zetcode

const val VERSION = "1.0.0"

@Deprecated("Use version $VERSION instead")
class OldClass

fun main() {

    val obj = OldClass()
}

VERSION 常量用于 Deprecated 注解消息中。注解中只能使用编译时常量。这确保了注解值在编译期间可用。

When 表达式中的常量

常量与 when 表达式配合良好,因为这些值在编译时已知。当使用常量时,编译器可以优化 when 表达式。

WhenConstants.kt
package com.zetcode

const val RED = 0xFF0000
const val GREEN = 0x00FF00
const val BLUE = 0x0000FF

fun getColorName(color: Int): String {
    return when (color) {
        RED -> "Red"
        GREEN -> "Green"
        BLUE -> "Blue"
        else -> "Unknown"
    }
}

fun main() {

    println(getColorName(RED)) // Output: Red
}

颜色常量在 when 表达式中使用。由于它们是编译时常量,编译器可以优化 when 表达式。这使得代码更有效率和可读。

数组中的常量

虽然你不能在 Kotlin 中创建 const 数组,但你可以使用常量作为数组大小或索引。这有助于使数组操作更具可读性和可维护性。

ArrayConstants.kt
package com.zetcode

const val MAX_SIZE = 10

fun main() {

    val numbers = IntArray(MAX_SIZE) { it * 2 }
    
    for (i in 0 until MAX_SIZE) {
        println(numbers[i])
    }
}

MAX_SIZE 常量用于定义数组大小并控制循环。对这些值使用常量可以使代码更具可维护性。只需要在一个地方进行更改。

接口中的常量

接口可以包含常量,这些常量然后可用于所有实现类。这些常量必须在接口的伴生对象中声明。

InterfaceConstants.kt
package com.zetcode

interface Vehicle {
    companion object {
        const val WHEELS = 4
        const val MAX_SPEED = 120
    }
}

class Car : Vehicle {
    fun printSpecs() {
        println("Wheels: $WHEELS, Max speed: $MAX_SPEED")
    }
}

fun main() {

    Car().printSpecs()
}

Vehicle 接口定义了所有车辆可能共享的常量。Car 类可以直接访问这些常量。这提供了一种在相关类之间共享公共常量的方法。

常量的最佳实践

来源

Kotlin 编译时常量文档

本教程深入介绍了 Kotlin 的 const 关键字,展示了如何声明和使用编译时常量。我们探讨了各种场景,包括顶层声明、伴生对象和接口常量。正确使用常量可以使你的代码更具可维护性和效率。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我写了 1400 多篇文章和 8 本电子书。我拥有超过八年的编程教学经验。

列出 所有 Kotlin 教程