value class 完全代替 typealias?
- 如果评论区没有及时回复,欢迎来公众号:ByteCode 咨询
- 公众号:ByteCode。致力于分享最新技术原创文章,涉及 Kotlin、Jetpack、算法、译文、系统源码相关的文章
这是 value class
第三篇文章,之前已经写了两篇文章,分别从不同的角度分析了 value class
。
在 Kotlin 1.5 宣布了一个重磅特性 value class 文章中介绍了
value class
是一个非常实用的特性,提高代码可读性同时还可以提高性能,详细分析了value class
和inline class
。在 容易被忽视的几个 Kotlin 细节, value class 执行效率竟然这么高 文章中详细分析了
value class
和data class
的性能,以及使用value class
需要注意的几个细节
这篇文章将会从 类型安全 、 占用内存 、执行效率 、使用场景 这几个角度来分析 value class
,通过这篇文章,你将学习到以下内容。
- 什么是
value class
? - 什么是
typealias
? typealias
无法保证类型安全typealias
同value class
一样不会创建额外的对象value class
和typealias
的执行效率typealias
和原始类型 String 对比value class
和typealias
对比
value class
和typealias
的优势以及使用场景
什么是 value class
value class
表示内联类,需要在主构造函数中传入一个参数,而且需要用 val
进行修饰, 编译成 Java 代码之后,会替换为传进去的值,代码如下所示。
|
正如你所见,编译后的 Java 代码并没有创建额外的对象,而是将在 Kotlin 中创建的对象 User
替换为传进去的值 DHL
。
什么是 typealias
在 Kotlin 源码中遇到长签名的表达式多多少少都会使用 typealias
,它的作用就是给类取一个别名。
typealias Password = String |
通过 typealias
关键字,给 String
类型取了一个别名 Password
,接下来就可以像使用 String
来使用 Password
。
在上一篇文章 容易被忽视的几个 Kotlin 细节, value class 执行效率竟然这么高 对比了 value class
和 data class
, 接下来一起分析一下 value class
和 typealias
的区别,value class
是否可以完全代替 typealias
。
Typealias 无法保证类型安全
String
类型可以表示很多东西,比如 用户名 、密码 等等,同样我们也可以通过 typealias
关键字给 用户名 、密码 取一个别名。
typealias Username = String |
这里有一个输入密码的函数 inputPassword(password: String)
参数是 String 类型,因此我们可以传入 typealias
别名 Username
,因为类型一样,赋值是兼容的,代码如下所示。
fun inputPassword(password: String) { } |
虽然这是一个输入密码的函数,但是如果调用者传入的参数是用户名,因为类型一样,赋值是兼容的,这种情况在编译的时候是无法检查出来,但是在运行的时候,可能会带来不可预知的后果。
而 value class
的出现,很好的帮助我们解决了这个问题,我们也可以通过 data class
或者其它的 class 来解决这个问题,但是会有额外的性能开销,详细分析请查看之前的文章 容易被忽视的几个 Kotlin 细节, value class 执行效率竟然这么高。
|
现在如果在往 inputPassword()
函数中,传入我们不想要的参数,编译的时候就会检查出来。
Typealias 同 value class 一样不会创建额外的对象
从内存的角度 value class
和 typealias
一样不会创建额外的对象,typealias
编译之后的代码如下所示。
typealias Password = String |
而 value class
编译之后的代码如下所示。
|
正如你所看到的,无论是 value class
还是 typealias
都没有额外创建对象的开销。
Value class 和 typealias 的执行效率
接下来我们从以下几个角度来看一下 value class
和 typealias
执行效率。
typealias
和原始类型 String 对比value class
和typealias
对比value class
和data class
对比(之前的文章已经分析过了,这里就忽略了)
Typealias 和原始类型 String 对比
通过 typealias
关键字给 String
类型取了一个别名 Password
,那么 Password
和原始类型 String
执行效率如何,我们用一个例子验证一下。
fun inputPassword(password: String) { } |
分别测试了 string
和 typealias
,他们的结果如下所示。
measure string time 5.475575 ms |
从结果来看基本上没有什么差别,原因在于编译之后的 Java 代码,会将 typealias
声明的别名,替换为原始类型 String
。
Value class 和 typealias 对比
接下来我们在来看一下 value class
和 typealias
的执行效率,代码很简单如下所示。
// typealias |
value class
和 typealias
的测试结果如下所示。
measure typealias time 6.437296 ms |
正如你所看到的,无论从内存、还是执行效率 value class
和 typealias
基本上是没有太大的差距,那么是不是可以使用 value class
完全代替 typealias
? 这显示是不可能的,虽然 value class
执行效率高,功能强大,但是它们的使用场景完全不同。
Value class 和 typealias 的优势以及使用场景
综合前面的内容和之前的两篇文章对 value class
的分析,value class
具有以下优势:
- 类型安全,防止调用者做出我们意想不到的事
- 占用更少的内存,执行效率更高
- 提高了代码的可读性
value class
是一个真实存在的类型,功能更强大,可以有构造函数、初始化函数、其他函数(getXXX()
、setXXX()
)等等,便于我们封装业务逻辑
而 data class
相比于 value class
最大的优势,支持多个参数,而 value class
只支持一个用 val
声明的参数,但是 value class
内存和执行效率远远高于 data class
。当数据量很大时,它们的差距也会越来越大。
measure data class time 6.790241 ms |
value class
具有这么多的优势,那么它的使用场景呢?其实没有固定的使用场景,我们可以在 Toast、单位之间的转换 (时间、距离)、定位、Json 序列化和反序列化等等场景中,都可以使用到 value class
, 当我们了解完它们的优缺点之后,可以从内存、执行效率等等更多维度考虑。
value class
虽然有很多优势,但是在某些场景下 typealias
比 value class
更具有优势,当我们使用高阶函数、Lambda 表达式、具有长签名的表达式的时候,使用 typealias
会更好,举个例子代码如下所示。
inline fun requestData(type: Int, call: (code: Int, type: Int) -> Unit) { |
方法参数中有一个 Lambda 表达式,未来也有可能随时改动 Lambda 表达式中的参数,如果通过 typealias
给 Lambda 表达式取一个别名,在使用的时候,使用别名除了提高可读性,也方便以后统一的修改,最后的代码如下所示。
typealias Callback = (code: Int, type: Int) -> Unit |
所以当我们使用高阶函数、长签名表达式的时候,可以考虑使用 typealias
。
如果有帮助点个赞就是对我最大的鼓励
代码不止,文章不停
欢迎关注公众号:ByteCode,持续分享最新的技术
最后推荐长期更新和维护的项目:
个人博客,将所有文章进行分类,欢迎前去查看 https://hi-dhl.com
KtKit 小巧而实用,用 Kotlin 语言编写的工具库,欢迎前去查看 KtKit
计划建立一个最全、最新的 AndroidX Jetpack 相关组件的实战项目以及相关组件原理分析文章,正在逐渐增加 Jetpack 新成员,仓库持续更新,欢迎前去查看 AndroidX-Jetpack-Practice
LeetCode / 剑指 offer / 国内外大厂面试题 / 多线程题解,语言 Java 和 kotlin,包含多种解法、解题思路、时间复杂度、空间复杂度分析
近期必读热门文章
- 容易被忽视的几个 Kotlin 细节, value class 执行效率竟然这么高
- 1分钟发布一个网站,不用域名、服务器,网站发布从未如此简单
- 这是最棒的效率工具集,打通 Notion x 云盘 x 其他笔记软件,写作、设计、开发都会用到工具
- Android 12 已来,你的 App 崩溃了吗?
- Kotlin 宣布一个重磅特性
- Google 宣布废弃 LiveData.observe 方法
- 使用 kotlin 需要注意的一个细节
- 影响性能的 Kotlin 代码(一)
- Jetpack Splashscreen 解析 | 助力新生代 IT 农民工 事半功倍
- 为数不多的人知道的 Kotlin 技巧及解析(三)
- 揭秘 Kotlin 中的 == 和 ===
- Kotlin 密封类进化了
- 本文作者:hi-dhl
- 本文标题:value class 完全代替 typealias?
- 本文链接:https://hi-dhl.com/2022/03/07/kotlin/18-valueclass/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 hi-dhl