[译]从Lombok迁移到Kotlin

简介: > 原文地址: https://dzone.com/articles/migrating-from-lombok-to-kotlin > 更短的代码不是目的,只有更可读的代码才是 作为一个Java开发者,最常见的抱怨是对Java语言冗长的抱怨。而其中出现最多的就是数据类。 数据类,或者元祖,或者record记录类,未来在Java语言可能会消失,但在那天之前,任何时间创建一个rest d

原文地址: 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或其他的特性。

目录
相关文章
|
1月前
|
编译器 Android开发 开发者
Android经典实战之Kotlin 2.0 迁移指南:全方位优化与新特性解析
本文首发于公众号“AntDream”。Kotlin 2.0 已经到来,带来了 K2 编译器、多平台项目支持、智能转换等重大改进。本文提供全面迁移指南,涵盖编译器升级、多平台配置、Jetpack Compose 整合、性能优化等多个方面,帮助开发者顺利过渡到 Kotlin 2.0,开启高效开发新时代。
73 0
|
安全 Java 编译器
又一巨头从 Java 迁移到 Kotlin,简直很无语。。
又一巨头从 Java 迁移到 Kotlin,简直很无语。。
165 0
又一巨头从 Java 迁移到 Kotlin,简直很无语。。
|
Java 测试技术 Android开发
【译】将 Android 项目迁移到 Kotlin 语言
本文讲的是【译】将 Android 项目迁移到 Kotlin 语言,这个程序是用 integration tests 和 unit tests 进行测试的, 而且本身全部是用 Java 写的。至少以前是这样的...
1521 0
|
安全 IDE Java
代码行数减少30-90%!多邻国从Java迁移到Kotlin的奇妙体验
英文学习 App Duolingo(多邻国)的 Android 版最初是使用 Java 开发的,并一直沿用了 5 年。两年后,它变成了 100% 的 Kotlin App!从代码可维护性和开发者满意度方面来看,这次迁移是一个巨大的成功。
|
Android开发
Gradle指南之从Groovy迁移到Kotlin
### 前言 最近写 Kotlin 写的有些着魔了,正好看到 Gradle 4.10 版本支持使用 Kotlin DSL 构建脚本,然后心血来潮的尝鲜了下,因为刚出来,相关的资料实在太少,**实际在迁移过程遇到不少问题,所以本文可能是第一篇非官方迁移指导文档,希望可以 save your time !** 好了,话不多说,马上开始迁移(踩坑)之旅 ### 准备工作 1. 确认你的
1941 0
|
8天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
21 1
|
1月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
37 4
|
2月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
98 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
2月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin中常见作用域函数
**Kotlin作用域函数概览**: `let`, `run`, `with`, `apply`, `also`. `let`安全调用并返回结果; `run`在上下文中执行代码并返回结果; `with`执行代码块,返回结果; `apply`配置对象后返回自身; `also`附加操作后返回自身
40 8