原文地址: https://dzone.com/articles/mi...更短的代码不是目的,只有更可读的代码才是html
做为一个Java开发者,最多见的抱怨是对Java语言冗长的抱怨。而其中出现最多的就是数据类。 数据类,或者元祖,或者record记录类,将来在Java语言可能会消失,但在那天以前,任什么时候间建立一个rest dto, jpa实体,领域对象,或者任何相似的,Java的冗余就出现了。在这篇文章里,我会介绍如何从Lombok迁移到Kotlin,以及从迁移中能得到的收益。java
// 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。api
尽管如此,在这篇博文中,我会主要介绍从Lombok迁移到Kotlin,由于这是一个从Kotlin开始的好机会,风险很低而且很容易理解,加上Kotlin提供比Java更多的好处,迁移到Kotlin数据类型是一个可让你代码库开始适配Kotlin的好开端。安全
小声明:尽管这篇文章主要介绍迁移到Kotlin,我并无说Lombok很差。它为标准Java代码提供了不少帮助。这仅仅是介绍如何在Lombok使用的地方来使用Kotlin。微信
对于不熟悉Lombok的人,Lombok是一个移除了Java代码冗余的生成类库。好比,在如下类,用Lombok类库,代码可能看起来是这样:jvm
`
import java.time.LocalDate;maven
import lombok.Value;ide
@Value函数
public class Person {gradle
private String name;
private LocalDate dateOfBirth;
}
`
这更好,不是吗? @Value声明,为类建立了有两个参数的final 构造类,get方法,equals,hashcode和toString方法。
因为上面相对于原生代码已是一个巨大的改进了,这片文章主要介绍迁移到Kotlin。下面看,咱们的初始例子能够被Kotlin重写成这样:
``data class Person(val name: String, val dateOfBirth: LocalDate)
``
这段代码作的与Lombok同样,生成了构造函数,一个toString, equals/hashcode这些。
因为这更短,更短的代码并非目标。而代码的可读性才是核心。在这个例子里,有人能够说两段代码的可读性同样,我也赞成。尽管这样,经过引入Kotlin版本,一样的可读性同样是个迁移到Kotlin的好缘由。以上代码能100%与其余的Java代码互操做。所以,将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支持。你能够简单这样给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: zhukunrong@yeah.net