Kotlin Academy · 课时

内联值类

无额外开销地封装

第 2 / 4 课13 个步骤

内联值类 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

封装问题

将基本类型封装在类中可以增加类型安全性,但通常需要付出堆分配的代价。值类可以在提供安全性的同时,让编译器在可能的情况下消除封装器。

声明值类

请使用 @JvmInline value class 标记一个类,并在主构造函数中声明恰好一个属性。它的行为类似一种独立类型。

@JvmInline
value class Password(val value: String)

fun main() {
    val p = Password("secret")
    println(p.value)
}

独立类型

与类型别名不同,值类是一种独立类型。在需要 Password 的地方,您不能误传原始的 String。

@JvmInline
value class Password(val value: String)

fun login(p: Password) = println("login with " + p.value)

fun main() {
    login(Password("hunter2"))
}

零开销

在运行时,编译器通常会内联底层值,因此不会额外分配对象。在大多数代码路径中,Password 会表示为普通的 String。

@JvmInline
value class Meters(val amount: Double)

fun main() {
    val d = Meters(5.0)
    println(d.amount) // stored inline as a Double
}

方法和属性

值类可以拥有函数和计算属性,就像普通类一样。

@JvmInline
value class Celsius(val degrees: Double) {
    fun toFahrenheit() = degrees * 9 / 5 + 32
}

fun main() {
    println(Celsius(100.0).toFahrenheit())
}

用于验证的初始化块

init 块可以让您在构造时验证包装的值,从而确保每个实例都有效。

@JvmInline
value class Percentage(val value: Int) {
    init {
        require(value in 0..100) { "out of range" }
    }
}

fun main() {
    println(Percentage(75).value)
}

计算属性

您可以添加根据唯一存储值计算得出的属性,让相关逻辑始终贴近类型。

@JvmInline
value class Seconds(val value: Int) {
    val asMinutes: Double get() = value / 60.0
}

fun main() {
    println(Seconds(120).asMinutes)
}

实现接口

值类可以实现接口,从而支持多态使用。请注意:当值类被当作接口类型处理时,这样做可能会强制进行装箱。

interface Describable {
    fun describe(): String
}

@JvmInline
value class Money(val cents: Int) : Describable {
    override fun describe() = "$" + cents / 100.0
}

fun main() {
    println(Money(1599).describe())
}

何时会发生装箱

当值被用作可空值、接口,或泛型集合中的元素时,包装对象会重新出现(即发生装箱)。在这些情况下,编译器会创建一个真正的对象——功能仍然正确,只是效率较低。

@JvmInline
value class Id(val raw: Int)

fun main() {
    val direct = Id(1)        // inlined
    val boxed: Id? = Id(2)    // boxed because nullable
    println("" + direct.raw + " " + boxed?.raw)
}

值类与数据类

data class 总会分配对象,并且可以容纳多个属性。value class 恰好只容纳一个属性,目标是实现零开销。对于围绕单个值构建的轻量、类型安全包装器,请选择值类。

为什么重要

值类可以帮助您:

  • 防止混淆类型相同的参数
  • 为基本类型附加验证
  • 通常无需承担运行时开销

当类型别名无法提供足够保障时,值类就是类型安全的解决方案。

快速检查

请检验您对内联值类的理解。

回顾

您学到了内联值类:

  • 使用带有一个属性的 @JvmInline value class 声明
  • 它是一种通常具有零开销的独立类型
  • 支持方法、计算属性和使用 init 进行验证
  • 在可空、泛型或接口场景中使用时会发生装箱

下一步:实际应用场景。

免费开始

用 AI 导师学习 Kotlin — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「内联值类」课时是免费的吗?

是的 — 「内联值类」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「内联值类」这节课中我会学到什么?

无额外开销地封装 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「内联值类」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 类型别名
  2. 内联值类
  3. 使用场景
  4. 限制
← 返回 Kotlin Academy