03.03 最新發布的Java 14 新特性之JEP 359: Records(Preview)為你詳解


最新發布的Java 14 新特性之JEP 359: Records(Preview)為你詳解


1. 前言

本月(2020-03) Java 14 就該正式發佈了,有一個 Java 社區呼喚已久的特性將作為 preview feature包含在 Java 14 中 ,這就是 JEP 359: Records。換句話說效果類似 lombok 的 @Data 註解,但是又不完全是, 在合適的場景中我們終於不用編寫樣板代碼了。今天我們就來感受一下。歡迎加入[微信圈子]程序員交流圈 交流編程經驗。

其實更像 Jvm 語言 kotlin 中的 data class

2. 傳統數據類

我們先來看看現在我們如何聲明一個數據類:

<code>public class Range {

private final int min;
private final int max;

public Range(int min, int max) {
this.min = min;
this.max = max;
}

public int getMin() {
return min;
}

public int getMax() {
return max;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Range range = (Range) o;
return min == range.min && max == range.max;
}

@Override
public int hashCode() {
return Objects.hash(min, max);
}

@Override
public String toString() {
return "Range{" +
"min=" + min +
", max=" + max +
'}';
}
}/<code>

我們來看看這個類的特點:

  • 沒有無參構造方法,需要初始化時對成員變量賦值
  • 成員變量只有 getter 方法。
  • 覆寫了 超類 Object 的 equals 、hashCode、toString 方法。

雖然我們可以藉助於第三方框架或者 IDE 很容易編寫這些樣板代碼,但是總歸要寫這些樣板代碼不是嗎?

3. 新的 Java Records

上面的冗長的代碼在 Java 14 中我們可以這麼寫:

<code>public record Range(int min, int max) {}/<code>

沒錯就是這個簡單!這個語法糖是不是有 “臥槽” 的感覺?我們聲明這種類使用record 標識(目前不知道 record 會不會上升到關鍵字的高度)。當你用record 聲明一個類時,該類將自動擁有以下功能:

  • 獲取成員變量的簡單方法,以上面代碼為例 min() 和 max() 。注意區別於我們平常getter的寫法。
  • 一個 equals 方法的實現,執行比較時會比較該類的所有成員屬性
  • 重寫 equals 當然要重寫 hashCode
  • 一個可以打印該類所有成員屬性的 toString 方法。
  • 請注意只會有一個構造方法。

因為這個特性是 preview feature,默認情況下是無法編譯和執行的。同樣以上面為例我們需要執行:

<code> $ javac -d classes --enable-preview --release 14 Range.java
$ java -classpath classes --enable-preview Range/<code>

Jshell 中運行

<code>jshell> Range r = new Range(10, 20);
r ==> Range[min=10, max=20]
jshell> r.min()
$5 ==> 10
jshell> r.toString()
$6 ==> "Range[min=10, max=20]"
jshell> r
r ==> Range[min=10, max=20]/<code>

雖然 record 聲明的類沒有 final 關鍵字,實際上它是一個不可變類。除了一些限制外,它依舊是一個普通的Java 類。因此,我們可以像添加普通類一樣添加邏輯。我們可以在構造實例時強制執行前提條件:

<code>public record Range(int min, int max) {
public Range {
if (min >= max)
throw new IllegalArgumentException("min should be less than max");
}
}/<code>

另外我們也可以給

Records 類增加普通方法、靜態屬性、靜態方法,這裡不再舉例;

**為了簡化語法糖的推理,不能在類內聲明成員屬性。**以下是錯誤的示範:

<code>public record Range(int min, int max) {
// 錯誤的示範
private String name;
}/<code>

4. 總結

今天對即將到來的 Java 14 的預覽特性 Java Records 進行了介紹。隨著Java 版本迭代的加快,Java 也逐漸跟上了時代的步伐,希望這門偉大的語言繼續煥發生機。更多我的技術文章請訪問 felord.cn[1]。


分享到:


相關文章: