内联类使用关键字 value 和 @JvmInline 注解声明,它只能有一个属性而且不能有 init 代码块和幕后字段

内联类有点像 Java 中的包装类型,Integer, Boolean 等等,而在使用内联类时,除非绝 对必要,否则类本身的信息不会在字节码中使用,而是将属性数据内联到类的使用处,可以 大大减少运行时的空间开销

@JvmInline  // For JVM backends
value class Password(private val s: String)

在生成的代码中,Kotlin 编译器为每个内联类保留一个包装器。内联类的实例可以在运行 时表示为包装器或者基础类型,为了生成性能最优的代码,编译器更倾向于使用基础类型。 比如:

// 不存在 'Password' 类的真实对象
// 在运行时,'securePassword' 仅仅包含 'String'
val securePassword = Password("Don't try this in production")

但如果将内联类用作其他类型时,其类型信息是必须的,所以会被装箱。比如:

interface I
 
@JvmInline
value class Foo(val i: Int) : I
 
fun asInline(f: Foo) {}
fun <T> asGeneric(x: T) {}
fun asInterface(i: I) {}
fun asNullable(i: Foo?) {}
 
fun <T> id(x: T): T = x
 
fun main() {
    val f = Foo(42)
 
    asInline(f)    // 拆箱操作: 用作 Foo 本身
    asGeneric(f)   // 装箱操作: 用作泛型类型 T
    asInterface(f) // 装箱操作: 用作类型 I
    asNullable(f)  // 装箱操作: 用作不同于 Foo 的可空类型 Foo?
 
    val c = id(f)
}