23

[译]从Lombok迁移到Kotlin

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwMTEwNzEyOQ%3D%3D&%3Bmid=2650009653&%3Bidx=1&%3Bsn=1e7d3a4dbfc004c04ca6d926c5d1c9f9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文地址: https://dzone.com/articles/migrating-from-lombok-to-kotlin

更短的代码不是目的,只有更可读的代码才是

译者:时序

作为一个Java开发者,最常见的抱怨是对Java语言冗长的抱怨。而其中出现最多的就是数据类。数据类,或者元祖,或者record记录类,未来在Java语言可能会消失,但在那天之前,任何时间创建一个rest dto, jpa实体,领域对象,或者任何类似的,Java的冗余就出现了。在这篇文章里,我会介绍如何从Lombok迁移到Kotlin,以及从迁移中能获得的收益。

// 40 Lines of Java code for a class with 2 properties

import java.time.LocalDate;

import java.util.Objects;

public class Person {

 private String name;

 private LocalDate dateOfBirth;

 public Person(String name, LocalDate dateOfBirth) {

 this.name \= name;

 this.dateOfBirth \= dateOfBirth;

 }

 public String getName() {

 return name;

 }

 public LocalDate getDateOfBirth() {

 return dateOfBirth;

 }

 @Override

 public boolean equals(Object o) {

 if (this \== o) return true;

 if (o \== null || getClass() != o.getClass()) return false;

 Person person \= (Person) o;

 return Objects.equals(name, person.name) &&

 Objects.equals(dateOfBirth, person.dateOfBirth);

 }

 @Override

 public int hashCode() {

 return Objects.hash(name, dateOfBirth);

 }

 @Override

 public String toString() {

 return "Person{" +

 "name='" + name + '\\'' +

 ", dateOfBirth=" + dateOfBirth +

 '}';

 }

}

要有效的使用数据类,你经常需要一组属性;一个构造函数,一组getter;也许也会有equals; hashcode和toString方法;另外在一些情况下,还有邪恶的setter到处都是。由于这是个常见问题,一些解决方案出现了 - Lombok是比较知名的,但其他还有AutoValue与Immutables。

尽管如此,在这篇博文中,我会主要介绍从Lombok迁移到Kotlin,因为这是一个从Kotlin开始的好机会,风险很低并且很容易理解,加上Kotlin提供比Java更多的好处,迁移到Kotlin数据类型是一个可以让你代码库开始适配Kotlin的好开端。

小声明:尽管这篇文章主要介绍迁移到Kotlin,我并没有说Lombok不好。它为标准Java代码提供了很多帮助。这仅仅是介绍如何在Lombok使用的地方来使用Kotlin。

什么是Lombok?

对于不熟悉Lombok的人,Lombok是一个移除了Java代码冗余的生成类库。比如,在以下类,用Lombok类库,代码可能看起来是这样:

`

import java.time.LocalDate;

import lombok.Value;

@Value

public class Person {

private String name;

private LocalDate dateOfBirth;

}

`

这更好,不是吗?@Value声明,为类创建了有两个参数的final 构造类,get方法,equals,hashcode和toString方法。

什么是Kotlin?

由于上面相对于原生代码已经是一个巨大的改进了,这片文章主要介绍迁移到Kotlin。下面看,我们的初始例子可以被Kotlin重写成这样:

``data class Person(val name: String, val dateOfBirth: LocalDate)

``

这段代码做的与Lombok一样,生成了构造函数,一个toString, equals/hashcode这些。

由于这更短,更短的代码并不是目标。而代码的可读性才是核心。在这个例子里,有人可以说两段代码的可读性一样,我也同意。尽管这样,通过引入Kotlin版本,同样的可读性一样是个迁移到Kotlin的好原因。以上代码能100%与其他的Java代码互操作。因此,将Kotlin引入到代码中不会有很大组里。

Lombok迁移Kotlin指南

以上只是个小例子,下面的表格展示了一个完整的如何迁移到Kotlin数据类型的概况。

特性 Lombok Kotlin 注释 Final类型本地变量 val val val是Kotlin关键字 可被重赋值的本地变量 var var var是Kotlin关键字 非空变量 @NonNull 不需要关键字 在Kotlin,默认类型都是非空,并需要用问号显示声明可为空的变量,如String? 自动资源管理(ARM) @Cleanup Closeable.use 例子:val result = FileInputStream("input.txt").use{input->//Process input} 生成get和set @Getter/@Setter 通过数据类中声明属性为var实现 如:data class Person(var name: String) 生成了 Person name的get和set. 生成toString @ToString 数据类的一部分 如:data class Person(var name: String) 生成了toString 生成equals和hashcode方法 @EqualsAndHashCode 数据类的一部分 如:data class Person(val name: String) 自动生成了Person的equas和toString 方法。 生成无参构造函数 @NoArgsConstructor 数据类提供,给所有参数一个默认值或引入一个第二构造函数 如:data class Person(val name: String = “”) 将一个默认值赋给了name并且生成了一个默认无参构造函数 或者,用一个第二构造函数: data class Person(var name: String) {   constructor() : this(“”) } 生成与属性数量一致的带参数构造函数 @RequiredArgsConstructor and @AllArgsConstructor 数据类型的一部分 例如:data class Person(val name: String) 自动为所有参数生成了构造函数 生成不可见数据类 @Data 数据类一部分,通过在属性上使用var声明 data class Person(var name: String) 自动生成了toString, hashCode, equals, 等 生成一个不可变数据类 @Value 数据类一部分,通过在属性上声明val 如:data class Person(var name: String)生成了Person的toString 用命名的属性来生成对象 @Builder Kotlin中的命名参数 Person(name = “Sergey”, age = 25) 转换checked异常到unchecked异常 @SneakyThrows 所有Kotlin代码调用的checked异常都是unchecked异常 Kotlin方法声明了@Throws,当被Java调用时,仍会抛出checked异常 用锁的同步方法 @Synchronized Kotlin withLock 方法。并不完全一样,但很相近了。另一个好选择是看看Kotlin协程coroutines someLock.withLock {    sharedResource.operation()} 延迟加载属性 @Getter(lazy=true) 委托属性 `by lazy` 自动logger @Log 无内置选项 但marker interface可以让这个属性更容易实现

就像上表看到的,大多数Lombok特性都可在Kotlin实现。其实,让Lombok最伟大的原因就是灵活。例如,很容易为一个类增加toString方法,而不用增加Equals/HashCode方法。在Kotlin,则没这么容易。

实践中,只需要一个toString方法,可能不太常见,不过这就是让你了解下Lombok比Kotlin更灵活一点。

如果给工程增加Kotlin支持

要开始迁移,你需要给你的工程增加Kotlin支持。你可以简单这样给Maven加adding Kotlin support to your Maven project, 或给Gradle加adding Kotlin support to your Gradle project.

同时使用Kotlin和Lombok不是个好主意,由于Kotlin源码编译与Lombok代码生成是在同一个时间段。结果,Kotlin代码不能使用Lombok生成的方法。你可以通过将代码放入一个独立工程来临时解决,但我建议彻底迁移,或者跟我做的一样,你可以给工程去LombokdeLombok the project 并慢慢迁移到Kotlin。使用什么方法取决于你工程的大小,但对于我们,最简单的就是去掉Lombok并转换到Kotlin。

结论

我希望通过这篇文章能将Kotlin引入你的项目。它应该是一个安全并可读的转换,提供了未来引入其他高级Kotlin特性的可能,比如协程,Kotlin类型安全DSL或其他的特性。

来自时序的博客

微信公众号「麦芽面包」,id「darkjune_think」

开发者/科幻爱好者/硬核主机玩家/业余翻译

交流Email: [email protected]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK