Kotlin - 值类 value class(内联类 inline class)

解决的问题

有时候需要将原生数据类型或String类型的参数通过构造封装在一个类中,然后提供一些方法对参数进行操作,使其使用起来成为一个强类型来提高代码健壮性。而一般我们写代码只是传递原生数据类型或String,JVM 会针对原生数据类型或String进行优化,但不会针对包装类做任何处理,使用包装类会创建对象意味着性能的损耗(内存占用,运行效率,GC回收)。

value class

  • 在Kotlin v1.3 推出的 inline class 被废弃,转而使用 v1.5 推出的 value class 会得到更多的优化,对类添加 @JvmInline 注解即可。
  • 只能在主构造中声明一个 val 参数,传入参数为 null 会失去内联效果(除了String,因为原生数据类型无法转为 null。)。没有 init{} 代码块,属性不能有幕后字段(没有延迟初始化、属性委托)。
  • 不能继承和被继承,可以实现接口但会失去内联效果。必须在顶层声明,枚举类、嵌套类、内部类都不能内联。
  • 反编译成 Java 代码并没有创建额外的对象,在 Kotlin 中创建的包装类实例被替换为构造中传进去的值。
  • 编译后的函数名称会被打乱,防止方法重载冲突(因为被替换成原生数据类型或String,若存在同名函数会导致参数列表一样)。当出现冲突使得 Java 无法调用形参接收内联类的函数(因为包装类型被替换成),对函数添加 @JvmName("XXX") 注解另行指定名称即可。
  • 可以使用 == 比较内容,无法使用 === 比较引用(既可以表示为基础类型或String,又可以表示为包装类类型,无意义)。
  • 受多态和泛型的影响,不一定会获得优化。在运行时被当成另一种类型(父类型,协变?)使用的时候会装箱(当做Any或者实现的接口类型),泛型的类型擦除也会产生装箱,在静态分析中被认为仅当做本身类型使用的时候会拆箱(当做基础类型或者String使用)。
@JvmInline
value class User(val name: String)

对比 typealias

typealiesvalue class
只是取别名,使用起来一样包装类,使用存在拆装箱操作
与原数据类型相同,同类型可以相互传参赋值强类型,提供类型安全
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值