原文地址: 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