在 Java 中,像 Integer
、Double
等都是 包装类,都需要创建对象 装箱 数值。
很显然 创建对象是 消耗额外内存的,而 对于优化这种问题,Kotlin 引入了 value class
,尽量避免装箱和脱箱。
一、声明语法
kotlin
@JvmInline
value class XXX(val value: Type)
使用 和 正常类,没有区别。
在 Jetpet Compose
中,Dp
就是典型的value class
应用:
kotlin
@JvmInline
value class Dp(val value: Float)
二、JVM实现分析
说明: value class
会(尽可能)避免创建包装类对象,而是直接使用 基本数据类型。而 对应的类成员方法 以 类静态方法 传入 value
值 来实现执行。
这里定义 尺寸 Pt
单位为例:
kotlin
@JvmInline
value class Pt(private val value: Int) {
fun print() {
println("pt: $value")
}
}
fun main() {
val pt = Pt(10)
pt.print()
}
通过 Show Kotlin Bytecode
-> Decompile
得到:
java
public final class Pt {
private final int value;
// print 转成了 静态方法
public static final void print_impl(int arg0) {
String var1 = "pt: " + arg0;
System.out.println(var1);
}
}
public final class MainKt {
public static final void main() {
// 优化成 基本类型 int,不需要 装箱
int pt = Pt.constructor-impl(10);
// 而 直接调用
Pt.print-impl(pt);
}
// $FF: synthetic method
public static void main(String[] args) {
main();
}
}
说明: 上面说到 尽可能 创建和使用 包装对象,但是 当 Pt?
这种可空的时候,就会使用 包装类 传递参数。
简单举例,创建 Pt
为参数的方法:
kotlin
// 编译 成 java 则是 testPt(int pt)
fun testPt(pt: Pt)
// 而 下面 则编译成 testPt(@Nullable Pt pt)
fun testPt(pt: Pt?)