编程后端开发人员

Kotlin中的内联类(值类)是什么,用途是什么,使用时有哪些限制?

用 Hintsage AI 助手通过面试

答案。

问题的历史

Kotlin引入了内联/值类(现在称为值类)的概念,以最小化处理原始类型和小结构的包装时的运行时开销。这个想法借鉴了其他语言(例如C#结构体),在没有失去类型安全的情况下,提高性能。

问题

创建包装类(例如,用于实体类型或标识符)而没有优化会导致内存中出现额外对象,影响性能,GC,并可能导致装箱/拆箱开销。通常希望获得严格的类型(例如,UserId而不是Int),但不实际创建对象。

解决方案

值类用value修饰符声明。在大多数情况下,JVM不会创建额外的对象——值类直接用其字段替换(内联)。这提供了类型安全和接近“简单Int”的性能。

代码示例:

@JvmInline value class UserId(val value: Int) fun showId(id: UserId) = println(id.value) val id = UserId(15) showId(id) // 没有创建单独的UserId对象

关键特性:

  • 类必须包含恰好一个属性(val或var),但该类型不能为nullable
  • 不支持继承(值类不能继承或被继承)
  • 一些限制:不可有init块,存储lateinit或未初始化属性,不能在所有情况下使用反射。

有陷阱的问题。

值类可以有多个属性吗?

不,值类只能包含一个属性。

// 错误: // value class Money(val amount: Int, val currency: String)

可以创建具有nullable属性的值类吗?

值类的值字段不能为nullable——只能是非null类型。

// 错误: // value class Name(val value: String?)

可以与值类使用继承吗?

值类不支持继承,不能是抽象类或密封类。

// 错误: // value class NewId(val value: Int): BaseId()

常见错误和反模式

  • 尝试将值类用于复杂结构(例如,具有多个字段)
  • 通过值类存储nullable值
  • 使用引用方法(例如,equals/hashCode方法可能在编译后端中表现异常)

实际例子

负面案例

开发者为具有两个属性的实体创建了值类(例如,一对Int和String),导致编译错误。

优点:

  • 尝试实现严格的类型 缺点:
  • 不可行,无法编译

正面案例

开发者将值类用于具有单个字段的标识符类型(例如,UserId),工作快速且安全。

优点:

  • 简洁和安全的代码
  • 没有运行时开销 缺点:
  • 只能与一个非nullable类型一起使用