按照六個月的傳統,Java 13 於2019年9月17日發布後,另一個非 LTS 版本 Java 14 計劃於2020年3月17日發布。
Java 14 功能
以下是 Java 14 的功能列表:
- Switch 表達式(標準)- JEP 361
- 對於 instanceof 的模式匹配(預覽)- JEP 305
- NullPointerExceptions 的幫助 – JEP 358
- Records(預覽)- JEP 359
- Text Blocks(第二個預覽)- JEP 368
- 打包工具(孵化器)- JEP 343
- G1 的 NUMA 感知內存分配 – JEP 345
- JFR 事件流 – JEP 349
- 非易失性映射的字節緩衝區 – JEP 352
- 在 macOS 上的 ZGC – JEP 364
- 在 Windows 上的 ZGC – JEP 365
- 外部內存訪問 API(孵化器)- JEP 370
Mac OS 上的 Java 14 安裝設置
- 開始使用Java 14,請從這裡下載JDK。
- 將tar文件複製並解壓縮到
/Library/Java/JavaVirtualMachines
中,如下所示:
$ cd /Library/Java/JavaVirtualMachines
$ sudo cp ~/Downloads/openjdk-14_osx-x64_bin.tar.gz /Library/Java/JavaVirtualMachines
$ sudo tar xzf openjdk-14_osx-x64_bin.tar.gz
$ sudo rm openjdk-14_osx-x64_bin.tar.gz
完成後,使用任何文本編輯器打開bash_profile
。我使用vim ~/.bash_profile
。將Java14的路徑設置為JAVA_HOME,保存更改,然後執行source ~/.bash_profile
以反映更改。
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home
最後,您可以使用Java 14編譯和運行程序。我們將使用JShell,這是一個用於快速測試新Java 14功能的交互式REPL命令行工具。
重要的是要注意,Java 14中發布的許多功能都是預覽版。這意味著雖然它們現在完全可用,但將來可能會進行修改。一些功能可能會在下一個版本中成為標準,或者被簡單地刪除。為了測試預覽功能,執行JShell或Java程序時需要明確設置--enable-preview
,如下所示:
jshell --enable-preview
javac --release 14 --enable-preview Author.java
在接下來的幾節中,讓我們討論一些語言和JVM功能。
推薦閱讀:在Linux上安裝Java 14
1. Switch Expressions
switch表達式在過去兩個版本中一直是一個預覽功能–Java 12和Java 13,現在終於在Java 14中獲得了永久性地位。
- Java 12引入了用於switch表達式的lambda語法,從而允許多個案例標籤進行模式匹配,同時防止了可能導致代碼冗長的fall-throughs。它還強制執行了完整的案例,如果沒有涵蓋所有輸入案例,則會產生編譯錯誤。
- Java 13,第二個預覽版引入了
yield
語句,用於從表達式返回值,而不是使用break
。
Java 14現在終於將這些功能定為標準了。
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(day.isEmpty())
yield "Please insert a valid day.";
else
yield "Looks like a Sunday.";
}
};
System.out.println(result);

注意:Yield並不是Java中的新關鍵字,它只是用於switch表達式中。
2. instanceof的模式匹配(預覽)
請任何Java開發人員展示他們的代碼庫,你會看到instanceof
條件在整個代碼中被很好地使用。具體而言,instanceof條件檢查通常後面跟著一個類型轉換。
Java 14通過使條件提取更加簡潔來消除這種冗長性。
Java 14之前:
if (obj instanceof Journaldev) {
Journaldev jd = (Journaldev) obj;
System.out.println(jd.getAuthor());
}
Java 14及以後:
if (obj instanceof Journaldev jd) {
System.out.println(jd.getAuthor());
}
在上述代碼中,只有在obj
的類型為Journaldev
時,實例jd
才會被賦值。該變量的作用域僅限於條件塊內。
3. 有用的NullPointerExceptions
NullPointerException對於任何開發人員來說都是一場噩夢。在Java 13之前,要調試臭名昭著的NPE是棘手的。開發人員必須倚賴其他調試工具或手動找出變量/方法為null,因為堆棧跟蹤僅顯示行號。
Java 14之前:
String name = jd.getBlog().getAuthor()
//堆棧跟蹤
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.main(NullPointerExample.java:5)
Java 14引入了一個新的JVM功能,提供更詳細的堆棧信息,如下所示:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Blog.getAuthor()" because the return value of "Journaldev.getBlog()" is null
at NullPointerExample.main(NullPointerExample.java:4)
注意:上述功能不是語言特性,而是運行時環境的增強。
4. Records(預覽)
A record is a data class that stores pure data. The idea behind introducing records is to quickly create simple and concise classes devoid of boilerplate code.
通常,在Java中,一個類需要實現equals()
、hashCode()
、getter和setter方法。儘管一些IDE支持自動生成此類,但代碼仍然冗長。使用record
,您只需以以下方式定義一個類。
record Author(){}
//or
record Author (String name, String topic) {}
Java 編譯器會自動產生構造函數、私有 final 欄位、存取器、equals
/hashCode
和 toString
方法。上述類別的自動生成 getter 方法為 name()
和 topic()
。
要查看生成的程式碼,請在使用 javac
編譯程式後,使用 javap Author
。下圖顯示了用於 record Author (String name, String topic) {}
的生成類別:

此外,我們可以以以下方式為記錄添加額外的欄位、方法和構造函數:
record Author (int id, String name, String topic) {
static int followers;
public static String followerCount() {
return "Followers are "+ followers;
}
public String description(){
return "Author "+ name + " writes on "+ topic;
}
public Author{
if (id < 0) {
throw new IllegalArgumentException( "id must be greater than 0.");
}
}
}
記錄內部定義的額外構造函數稱為緊湊構造函數。它不包含任何參數,只是規範構造函數的擴展。
A compact constructor wouldn’t be generated as a separate constructor by the compiler. Instead, it is used for validation cases and would be invoked at the start of the main constructor.
關於記錄的一些重要事項:
- A record can neither extend a class nor it can be extended by another class. It’s a final class.
- 記錄不能是抽象的
- 記錄不能擴展任何其他類別,也不能在主體內定義實例欄位。實例欄位必須僅在狀態描述中定義
- 宣告的欄位為私有和 final
- 記錄的主體允許靜態欄位和方法
推薦閱讀: Java Records
4.1) 記錄的參考字段內的值可以被改變
重要的是要注意,對於定義為對象的字段,只有參考是不可變的。底層值可以被修改。以下示例顯示了一個記錄,其中 ArrayList 被修改。正如您所看到的,每當 ArrayList 被更改時,值都會被修改。

4.2) 記錄可以實現接口
以下代碼示例展示了使用記錄實現接口的示例:以下是在 JShell 中執行上述代碼的輸出:
record Author(String name, String topic) implements Information {
public String getFullName() {
return "Author "+ name + " writes on " + topic;
}
}
interface Information {
String getFullName();
}

4.3) 記錄支持多個構造函數
記錄允許聲明多個構造函數,可以帶參數,也可以不帶參數,如下所示:
record Author(String name, String topic) {
public Author() {
this("NA", "NA");
}
public Author(String name) {
this(name, "NA");
}
}
4.4) 記錄允許修改存取方法
雖然記錄確實為在狀態描述中定義的字段生成公共存取方法,但它們也允許您在內容中重新定義存取方法,如下所示:
record Author(String name, String topic) {
public String name() {
return "This article was written by " + this.name;
}
}
4.5) 在運行時檢查記錄及其組件
記錄為我們提供了isRecord()
和getRecordComponents()
,以檢查該類是否為記錄,並查看其字段和類型。下面的示例顯示了實現的方式:

儘管在上述代碼示例中我們添加了額外的字段和方法,但請確保不要過度使用。記錄被設計為純粹的數據承載器,如果您希望實現大量額外的方法,最好還是回歸到普通類別。
5. 文本區塊(預覽)
Text Blocks 在 Java 13 中作为预览功能引入,旨在实现轻松创建多行字符串文字。它在轻松创建 HTML、JSON 或 SQL 查询字符串方面非常有用。
在 Java 14 中,Text Blocks 仍处于预览阶段,并有一些新的添加。现在我们可以使用:
- 反斜杠来显示漂亮的多行字符串块。
\s
用于考虑默认情况下编译器忽略的尾随空格。它保留其前面的所有空格。
String text = """
Did you know \
Java 14 \
has the most features among\
all non-LTS versions so far\
""";
String text2 = """
line1
line2 \s
line3
""";
String text3 = "line1\nline2 \nline3\n"
//text2 和 text3 相等。
参考资料: OpenJDK 14
Source:
https://www.digitalocean.com/community/tutorials/java-14-features