注册

Kotlin1.8新增特性,进来了解一下

大家好,之前我已经写过了分析kotlin1.5、1.6、1.7、1.9插件版本新增的一些特性,唯独kotlin1.8的特性还没好好讲讲,本篇文章就带大家好好分析下kotlin1.8新增了那些特性,能对我们日常开发带来哪些帮助。


其中Kotlin1.8.0提供的特性有限,本篇文章主要是分析Kotlin1.8.20提供的一些新特性。下面是支持该插件的IDE对应版本:



一. 提供性能更好的Enum.entries替代Enum.values()



在之前,如果我们想遍历枚举内部元素,我们通常会写出以下代码:


enum class Color(val colorName: String, val rgb: String) {
RED("Red", "#FF0000"),
ORANGE("Orange", "#FF7F00"),
YELLOW("Yellow", "#FFFF00")
}

fun main() {
Color.values().forEach {
println("${it.rgb}--${it.colorName}--${it.name}")
}
}

但是不知道大家是否清楚,Color.values() 其实存在性能问题,换句话说,每调用一次该方法,就会触发重新分配一块内存,如果调用的频率过高,就很可能引发内存抖动


我们可以反编译下枚举类简单看下原因:



Color.values()每次都会调用Object.clone()方法重新创建一个新的数组,这就是上面说的潜在的性能问题,github上也有相关的问题链接,感兴趣的可以看下:HttpStatus.resolve allocates HttpStatus.values() once per invocation


同时Color.values()返回的是一个数组,而在我们大多开发场景中,可能集合使用的频率更高,这就可能涉及到一个数组转集合的操作。


基于以上考虑,Kotlin1.8.20官方提供了一个新的属性:Color.entries这个方法会预分配一块内存并返回一个不可变集合,多次调用也不会产生潜在的性能问题


我们简单看下使用:


fun main() {
Color.entries.forEach {
println("${it.rgb}--${it.colorName}--${it.name}")
}
}

输出:



同时我们也可以从反编译的代码中看出区别:



不会每次调用都重新分配一块内存并返回。


如果想要使用这个特性,可以加上下面配置:


compileKotlin.kotlinOptions {
languageVersion = "1.9"
}

另外多说一下,IntelliJ IDEA 2023.1版本也会检测代码中是否存在Enum.values()的使用,存在就提示使用Enum.entries代替。


二. 允许内联类声明次级构造函数



内联类在Kotlin1.8.20之前是不允许带body的次级构造函数存在的,也就是说下面的代码运行会报错:


@JvmInline
value class Person( val fullName: String) {
constructor(name: String, lastName: String) : this("$name $lastName") {
check(lastName.isNotBlank()) {
"Last name shouldn't be empty"
}
}
}

fun main() {
println(Person("a", "b").fullName)
}

运行看下结果:



如果没有次级构造函数body,下面这样写是没问题的:


    constructor(name: String, lastName: String) : this("$name $lastName") 

如果想要支持带body的次级构造函数,只需要在kotlin1.8.20插件版本上和上一个特性一样增加languageVersion = "1.9"配置即可。


然后上面的代码块运行就没问题了,我们看下输出:


fun main() {
println(Person("a", "").fullName)
}


准确的执行了次级构造函数body内的逻辑。


三. 支持java synthethic属性引用



这个特性用文字不好解释,我们直接通过代码去学习下该特性。


当前存在一个类Person1


public class Person1 {
private String name;
private int age;

public Person1(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}

在Kotlin1.8.20之前,以下这种写法是会报错的:



而是必须改成sortedBy(Person1::getAge)才能运行通过。


和上面特性一样,如果想要支持Person1::age这种引用方式,只需要在kotlin1.8.20插件版本上和上一个特性一样增加languageVersion = "2.1"配置即可。



PS:请注意,Kotlin官方网站提示配置languageVersion = "1.9" 就能使用上面的实验特性,但是编译器还是提示报错,然后你找报错提示信息改成了languageVersion = "2.1" 就正常了。




四. 新Kotlin K2编译器的更新



就是说目前Kotlin K2编译器还是一个实验阶段,不过Kotlin官方在其stable的路上又增加了一些更新:



  1. 序列化插件的预览版本;
  2. JS IR编译器的alpha支持;
  3. Kotlin2.0版本特性的引入;

如果大家想要体验下最新版的Kotlin K2编译器,增加配置:languageVersion ="2.0"即可。


五. Kotlin标准库支持AutoCloseable



这个AutoCloseable 接口就是用来支持资源关闭的,搭配提供的use扩展函数,就能帮助我们在资源流使用完毕后自动关闭。


Kotlin之所以在标准库中支持,应该是想要支持多平台吧。


六. Kotlin标准库支持Base64编解码


这里不做太多介绍,看下面的使用例子即可:



七. Kotlin标准库@Volatile支持Kotlin/Native


@Volatile注解在Kotlin/JVM就是保证线程之间可见性以及有序性的,kotlin官方在Kotlin/Native中也支持了该注解使用,有兴趣的可以实战试下效果。


总结


本篇文章主要是介绍了Kotlin1.8版本新增的一些特性,主要挑了一些我能理解的、常用的一些特性拉出来介绍,希望能对你有所帮助。


历史文章


两个Kotlin优化小技巧,你绝对用的上


浅析一下:kotlin委托背后的实现机制


Kotlin1.9.0-Beta,它来了!!


聊聊Kotlin1.7.0版本提供的一些特性


聊聊kotlin1.5和1.6版本提供的一些新特性


kotlin密封sealed class/interface的迭代之旅


优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!


@JvmDefaultWithCompatibility优化小技巧

,了解一下~

0 个评论

要回复文章请先登录注册