Java14的一些新特性預先預覽

前言

本文引自oracle官網,地址:

https://blogs.oracle.com/javamagazine/java-14-arrives-with-a-host-of-new-features

這次版本Java14帶來了許多新特性,與前兩個版本相比(Java12,Java 13),Java 14包含了更多的新特性,其中大多數旨在簡化編碼。

Java 14計劃於3月17日發佈。版本14包含的JEPs(Java Enhancement Proposals)比Java 12和13的總和還多。具體新增的JEP可查看:https://openjdk.java.net/projects/jdk/14/

JEP:jdk改進提案,每當需要有新的設想時候,JEP可以在JCP之前或者同時提出非正式的規範,被正式認可的JEP正式寫進JDK的發展路線圖並分配版本號。

JCP(Java Community Process) 是一個開放的國際組織,主要由Java開發者以及被授權者組成,職能是發展和更新。

JSR:java規範提案,新特性的規範出現在這一階段,是向JCP提出新增一個標準化技術規範的正式請求,請求可以來自小組/項目,JEP,JCP成員或者java社區成員的提案,每個java版本都由相應的JSR支持。

特性

1.switch表達式

改進的switch表達式,最初作為預覽出現在Java 12和Java 13中,現在已經完全成為Java 14的一部分。

“預覽”:是指為了收集反饋,這些特性可能會隨時改變,後面根據反饋結果,這些特性甚至可能會被移除。但是通常大多數預覽特性最後都會在Java中固定下來。

新的switch表達式,編寫更加的方便,減小了BUG出現的可能,因為它沒有fall-through行為。可以使用箭頭操作符,讓代碼更可觀。

<code>var log = switch (event) {
case PLAY -> "User has triggered the play button";
case STOP, PAUSE -> "User needs a break";
default -> {
String message = event.toString();
LocalDateTime now = LocalDateTime.now();
yield "Unknown event " + message +
" logged on " + now;
}
};/<code>

2.文本塊

Java 13引入了文本塊作為預覽特性。文本塊使使用多行字符串文字更容易。這個特性將在Java 14中進行第二輪預覽,幷包含一些調整。平常編寫代碼時,經常會遇到拼接字符串,可能還會有出現多行。

如下:

<code>String html = "" +
"\\n\\t" + "" +
"\\n\\t\\t" + "

\"Java 14 is here!\"

" +
"\\n\\t" + "" +
"\\n" + "";/<code>

看起來格式較亂,可讀性也比較不好。新的文本塊,就可以簡化這一過程,只需使用三引號作為文本塊的起始和結束標記,就能編寫出更優雅的代碼:

<code>String html = """


"Java 14 is here!"



""";/<code>

在Java 14中添加了兩個新的轉義序列。首先,可以使用新的轉義序列\\s來表示單個空格。其次,可以使用反斜槓“\\”來替代在行尾插入換行的字符。當有一個很長的行要拆分,可以用它,方便文本塊的可讀。

<code>String literal =

"Lorem ipsum dolor sit amet, consectetur adipiscing " +

"elit, sed do eiusmod tempor incididunt ut labore " +

"et dolore magna aliqua.";/<code>

用“\\”

<code>String text = """
Lorem ipsum dolor sit amet, consectetur adipiscing \\
elit, sed do eiusmod tempor incididunt ut labore \\
et dolore magna aliqua.\\
""";/<code>

3.instanceof的模式匹配

Java 14引入了一個預覽特性,它有助於消除在用instanceof檢查之前進行顯式轉換的需要。例如,請看以下代碼:

<code>if (obj instanceof Group) {
Group group = (Group) obj;

// use group specific methods
var entries = group.getEntries();
}/<code>

用這個新的預覽特性重構,如下:

<code>if (obj instanceof Group group) {
var entries = group.getEntries();
}/<code>

上面的條件檢查斷言obj是Group類型,所以為什麼還需要在再一次的聲明obj是Group類型?這將會帶來出錯的可能性。這種更簡潔的語法可以去掉Java程序裡的大多數強制類型轉換,再比如:

<code>@Override public boolean equals(Object o) { 
return (o instanceof CaseInsensitiveString) &&
((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}/<code>

通過刪除多餘的顯式轉換,可以將上面的代碼簡化為以下形式

<code>@Override public boolean equals(Object o) { 
return (o instanceof CaseInsensitiveString cis) &&
cis.s.equalsIgnoreCase(s);
}/<code>

這是一個很好的預覽功能,它為以後的模式匹配帶來一個方向。模式匹配的思想是在一定的條件下,為提取對象的成分提供一種語法方便的語言特徵。instanceof運算符就是這種情況,因為條件是類型檢查,而提取操作正在調用適當的方法或訪問特定字段。

換句話說,這個預覽功能只是一個開始,它可以幫助進一步減少冗長,從而減少出現錯誤的可能性。

4.Record

這個特性遵循了減少Java中的冗長性並幫助開發人員編寫更簡潔的代碼。Record主要用於特定領域的類,它的主要功能就是存儲數據,而沒有任何自定義的行為。這裡舉個例子,申明一個類BankTransaction,它有如下屬性:date, amount, description,平常我們用IDE自動生成構造器,hashcode方法,toString方法,get/set方法。

<code>public class BankTransaction {
private final LocalDate date;
private final double amount;
private final String description;


public BankTransaction(final LocalDate date,
final double amount,
final String description) {
this.date = date;
this.amount = amount;
this.description = description;
}

public LocalDate date() {
return date;
}

public double amount() {
return amount;
}

public String description() {
return description;
}

@Override
public String toString() {
return "BankTransaction{" +
"date=" + date +
", amount=" + amount +
", description='" + description + '\\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BankTransaction that = (BankTransaction) o;
return Double.compare(that.amount, amount) == 0 &&
date.equals(that.date) &&
description.equals(that.description);
}

@Override
public int hashCode() {
return Objects.hash(date, amount, description);
}
}/<code>

Java 14提供了一種方法可以解決這種冗餘,可以更清晰地表達目的:這個類的唯一目的就是將數據整合在一起。Record會提供equals、hashCode和toString方法的實現。BankTransaction類重構如下:

<code>public record BankTransaction(LocalDate date,
double amount,
String description) {}/<code>

除了構造函數和getter之外,還可以查看獲得equals、hashCode和toString的實現。但需要用如下命令

<code>javac --enable-preview --release 14 BankTransaction.java/<code>

5.NullPointerException

NullPointerException這個錯誤,相信開發都遇到過,再熟悉不多了。我們可能寫過類似如下面的代碼。

<code>var name = user.getLocation().getCity().getName();/<code>

你可能會得到如下的錯誤:

<code>Exception in thread "main" java.lang.NullPointerExceptionat
NullPointerExample.main(NullPointerExample.java:5)/<code>

如果現在生產環境的日誌中,會導致調試非常困難,因為並沒有顯示的指出那塊出現空指針異常。

getLocation()和getCity(),都可能會返回null。實際上,變量user也可能是null。因此,無法判斷是誰導致了NullPointerException。

在Java 14中,新的JVM特性可以顯示更詳細的診斷信息:

<code>Exception in thread "main" java.lang.NullPointerException: 
Cannot invoke "Location.getCity()" because the return value of "User.getLocation()"
is nullat NullPointerExample.main(NullPointerExample.java:5)/<code>

這樣可以快速的指出錯誤的地方:getCity()無法被調用,User.getLocation()的返回值為null

增強版本的診斷信息只有在使用下述標誌運行Java時才有效:

-XX:+ShowCodeDetailsInExceptionMessages

例如:

java -XX:+ShowCodeDetailsInExceptionMessages NullPointerExample

在Java的未來版本中,這個特性可能會在默認情況下啟用。此增強功能不僅可用於方法調用,還可用於可能導致NullPointerException的其他地方,包括字段訪問、數組訪問和賦值。

以上就是Java14的一些新特性的預覽,具體內容還是以官網正式發佈為準。總的來說,JAVA開發越來越方便了,簡化了JAVA很多的冗餘的代碼。小夥伴們你們現在用到JAVA哪個版本了?覺得哪個版本好用尼?


分享到:


相關文章: