Java 14 新特性解析與代碼示例

Java 14 新特性解析與代碼示例

文章目錄

  • Java 14 新特性解析與代碼示例
    • 1. 開關表達式(Switch Expressions)
    • 2. 記錄類型(Records)
    • 3. 文本塊(Text Blocks)
    • 4. instanceof的模式匹配(Pattern Matching for instanceof)
    • 5. 更有幫助的NullPointerException(Helpful NullPointerExceptions)
    • 6. 其他特性
    • 7. 版本演進與選擇建議
    • 8. 結語

Java 14(2020年3月發布)為Java開發者帶來了多項新特性和改進,旨在提升代碼的可讀性、簡潔性和調試效率。本文將深入探討Java 14的五大核心特性:開關表達式(Switch Expressions)、記錄類型(Records)、文本塊(Text Blocks)、instanceof的模式匹配(Pattern Matching for instanceof)以及更有幫助的NullPointerException(Helpful NullPointerExceptions)。每個特性都將通過詳細的解釋和完整的代碼示例進行說明,并與舊方法進行對比,以展示其優勢。以下是關鍵要點和詳細內容。

關鍵要點

  • 開關表達式(Switch Expressions):Java 14將開關表達式標準化,允許switch語句作為表達式返回一個值,消除了break語句的需求,使代碼更簡潔、更安全。
  • 記錄類型(Records):作為預覽特性,Records提供了一種簡潔的方式來定義不可變數據類,自動生成構造器、訪問器和常見方法,減少了樣板代碼。
  • 文本塊(Text Blocks):作為預覽特性,文本塊簡化了多行字符串的定義,消除了字符串拼接和轉義字符的麻煩,特別適合HTML、JSON等場景。
  • instanceof的模式匹配:作為預覽特性,允許在類型檢查時直接聲明變量并自動轉換類型,減少了顯式類型轉換的冗余代碼。
  • 更有幫助的NullPointerException:通過更詳細的異常消息,明確指出哪個變量為null,顯著提升了調試效率。

在這里插入圖片描述

1. 開關表達式(Switch Expressions)

開關表達式(JEP 361)是Java 14中標準化的特性,最初在Java 12和13中作為預覽特性引入。它通過以下方式改進了傳統switch語句:

  • 新語法:使用->代替:,消除了break語句的需要。
  • 多值case:支持在單個case中指定多個值(如case 1, 3, 5)。
  • 返回值:switch可以作為表達式直接返回值,使用yield關鍵字處理復雜邏輯。
  • 強制完整性:對于非枚舉類型,switch表達式必須覆蓋所有可能的分支。

傳統switch語句的問題

  • 容易發生"穿透",如果遺漏break,會導致意外執行后續case。
  • 不能直接返回值,需額外定義變量。

代碼示例

public class SwitchExpressionDemo {public static void main(String[] args) {int month = 2; // February// 傳統switch語句 - 需要break和額外變量int days;switch (month) {case 1:case 3:case 5:case 7:case 8:case 10:case 12:days = 31;break;case 4:case 6:case 9:case 11:days = 30;break;case 2:days = 28; // 非閏年break;default:days = -1; // 無效月份break;}System.out.println("傳統方式 - Days in month: " + days);// 開關表達式 - 簡潔安全int daysExpr = switch (month) {case 1, 3, 5, 7, 8, 10, 12 -> 31; // 多值casecase 4, 6, 9, 11 -> 30;case 2 -> 28; // 非閏年default -> -1; // 無效月份};System.out.println("開關表達式 - Days in month: " + daysExpr);// 使用yield處理復雜邏輯String day = "Monday";String result = switch (day) {case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> {System.out.println("工作日!");yield "Weekday"; // yield返回值}case "Saturday", "Sunday" -> {System.out.println("周末!");yield "Weekend";}default -> "Unknown";};System.out.println("Result: " + result);}
}

優點

  • 減少了樣板代碼,提高了可讀性
  • 消除了穿透問題,增強了代碼安全性
  • 支持在表達式中直接使用switch,增加了靈活性

注意事項

  • 開關表達式必須是完整的,編譯器會檢查是否覆蓋所有可能值
  • 不能混用:->語法
  • yield僅在switch塊內返回值,不同于return

2. 記錄類型(Records)

記錄類型(JEP 359)是Java 14的預覽特性,旨在為不可變數據類提供簡潔的定義方式。Records自動生成以下內容:

  • 不可變字段(final)
  • 規范構造器(Canonical Constructor)
  • 訪問器方法(Accessor Methods)
  • equals()hashCode()toString()方法

注意:Records是Java 14的預覽特性,編譯和運行時需添加參數:

  • 編譯:javac --enable-preview --release 14
  • 運行:java --enable-preview

傳統類的問題

  • 需要手動編寫大量樣板代碼,如構造器、訪問器和方法
  • 容易出錯,尤其是在實現equals()hashCode()

代碼示例

public class RecordDemo {// 傳統類 - 需要大量樣板代碼public static class Point {private final int x;private final int y;public Point(int x, int y) {this.x = x;this.y = y;}public int getX() { return x; }public int getY() { return y; }@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Point point = (Point) o;return x == point.x && y == point.y;}@Overridepublic int hashCode() {return Objects.hash(x, y);}@Overridepublic String toString() {return "Point{x=" + x + ", y=" + y + "}";}}// Record - 一行定義等效功能public record PointRecord(int x, int y) {// 緊湊構造器 - 可添加驗證邏輯public PointRecord {if (x < 0 || y < 0) {throw new IllegalArgumentException("坐標不能為負數");}}// 添加自定義方法public double distanceTo(PointRecord other) {return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));}// 添加轉換方法public PointRecord withX(int newX) {return new PointRecord(newX, this.y);}}public static void main(String[] args) {Point point = new Point(3, 4);System.out.println("傳統類: " + point);PointRecord record = new PointRecord(3, 4);System.out.println("Record: " + record);System.out.println("Distance to (0,0): " + record.distanceTo(new PointRecord(0, 0)));// 使用轉換方法PointRecord moved = record.withX(5);System.out.println("Moved point: " + moved);}
}

優點

  • 顯著減少樣板代碼
  • 明確表達不可變數據類的意圖
  • 支持自定義方法和構造器,增加靈活性

注意事項

  • Records是預覽特性(Java 16中轉正)
  • Records不可繼承其他類,但可實現接口
  • 適合數據傳輸對象(DTO)等場景,不適合需要可變性的類

3. 文本塊(Text Blocks)

文本塊(JEP 368)是Java 14的預覽特性,旨在簡化多行字符串的定義。它們使用三引號(""")定義,保留原始格式,消除了字符串拼接和轉義字符的需要。

注意:文本塊是預覽特性,編譯和運行參數同Records。該特性在Java 15中轉正。

傳統字符串的問題

  • 需要使用\n+進行拼接,代碼復雜且不易讀
  • 嵌入HTML、JSON等內容時,轉義字符(如\")增加復雜性

代碼示例

public class TextBlockDemo {public static void main(String[] args) {// 傳統字符串 - 需要拼接和轉義String htmlTraditional = "<html>\n" +"<body>\n" +"<h1>Hello, World!</h1>\n" +"</body>\n" +"</html>";System.out.println("傳統字符串:\n" + htmlTraditional);// 文本塊 - 保持原始格式String htmlTextBlock = """<html><body><h1>Hello, World!</h1></body></html>""";System.out.println("文本塊:\n" + htmlTextBlock);// 使用轉義字符 - 抑制換行String noNewline = """Line one \Line two""";System.out.println("無換行:\n" + noNewline);  // 輸出: Line one Line two// 使用轉義字符 - 顯式插入空格String preserveSpace = """one    \stwo    \s""";System.out.println("保留空格:\n" + preserveSpace);// JSON示例String json = """{"name": "張三","age": 30,"email": "zhangsan@example.com"}""";System.out.println("JSON文本塊:\n" + json);}
}

縮進規則
文本塊以結束符"""的位置為基準,自動去除每行前的公共空白:

String text = """HelloWorld!"""; 
// 實際存儲:"Hello\n  World!"

新轉義字符

  • \:抑制換行
  • \s:顯式插入空格(避免行尾空格被忽略)

優點

  • 提高多行字符串的可讀性
  • 減少轉義字符的使用
  • 適合嵌入復雜文本格式

注意事項

  • 避免在復雜表達式中內聯使用文本塊
  • 注意縮進規則,避免意外空白

4. instanceof的模式匹配(Pattern Matching for instanceof)

instanceof的模式匹配(JEP 305)是Java 14的預覽特性,允許在類型檢查時直接聲明變量并自動轉換類型,簡化了代碼。

注意:此特性是預覽特性(Java 16中轉正),編譯運行參數同前。

傳統instanceof的問題

  • 需要顯式類型轉換,增加代碼冗余
  • 容易出錯,尤其是在復雜類型層次結構中

代碼示例

public class PatternMatchingDemo {// 使用繼承層次結構abstract static class Animal {}static class Cat extends Animal {void meow() { System.out.println("喵喵!"); }}static class Dog extends Animal {void woof() { System.out.println("汪汪!"); }}public static void main(String[] args) {Animal animal = new Cat();// 傳統instanceof - 需要顯式轉換if (animal instanceof Cat) {Cat cat = (Cat) animal;cat.meow();} else if (animal instanceof Dog) {Dog dog = (Dog) animal;dog.woof();}// 模式匹配 - 合并檢查和轉換if (animal instanceof Cat cat) {cat.meow(); // 直接使用cat變量} else if (animal instanceof Dog dog) {dog.woof();}// 在表達式中使用String sound = (animal instanceof Cat cat) ? "喵喵" : (animal instanceof Dog dog) ? "汪汪" : "未知";System.out.println("動物叫聲: " + sound);}
}

優點

  • 合并類型檢查和轉換,減少代碼量
  • 提高代碼可讀性和安全性
  • 模式變量僅在匹配時有效,限制了作用域

注意事項

  • 模式變量是final的,不能重新賦值
  • 在復雜條件表達式中使用需謹慎

5. 更有幫助的NullPointerException(Helpful NullPointerExceptions)

Helpful NullPointerExceptions(JEP 358)是Java 14的標準特性,通過提供更詳細的異常消息,幫助開發者快速定位null變量。

傳統NPE的問題

  • 僅提供行號,難以確定具體哪個變量為null
  • 在復雜方法鏈中,調試耗時

實現機制:JVM在類文件中記錄局部變量表(LocalVariableTable)信息,使異常能定位具體變量。

代碼示例

public class HelpfulNPEDemo {static class PersonalDetails {String getEmailAddress() { return null; }}static class Employee {PersonalDetails getPersonalDetails() { return null; }}public static void main(String[] args) {Employee employee = null;// 傳統NPE - 只有行號信息try {String emailAddress = employee.getPersonalDetails().getEmailAddress().toLowerCase();} catch (NullPointerException e) {System.out.println("傳統NPE信息:");e.printStackTrace();}// 更好的實踐:使用Objects.requireNonNulltry {String email = Objects.requireNonNull(employee, "employee不能為空").getPersonalDetails().getEmailAddress();} catch (NullPointerException e) {System.out.println("\n使用非空校驗后的異常:");e.printStackTrace();}}
}

輸出對比

  • 傳統NPE(Java 13及之前):

    傳統NPE信息:
    java.lang.NullPointerExceptionat HelpfulNPEDemo.main(HelpfulNPEDemo.java:14)
    
  • Helpful NPE(Java 14+):

    java.lang.NullPointerException: Cannot invoke "HelpfulNPEDemo$Employee.getPersonalDetails()" because "employee" is nullat HelpfulNPEDemo.main(HelpfulNPEDemo.java:10)
    

優點

  • 明確指出null變量,簡化調試
  • 默認啟用,無需額外配置
  • 僅對JVM拋出的NPE有效,自定義NPE不受影響

注意事項

  • 在極端性能敏感場景可考慮禁用(不推薦)
  • 結合Objects.requireNonNull使用效果更佳

6. 其他特性

Java 14還包括以下特性:

  • Foreign Memory Access API(JEP 370):孵化特性,提供安全高效的外部內存訪問
  • Packaging Tool(JEP 343):孵化特性,用于創建原生安裝包
  • ZGC on Windows and macOS(JEP 364, 365):實驗特性,將低延遲垃圾收集器擴展到Windows和macOS
  • NUMA-Aware Memory Allocation for G1(JEP 345):優化G1垃圾收集器在NUMA架構上的性能
  • JFR Event Streaming(JEP 349):支持實時監控JDK Flight Recorder數據

由于篇幅限制,這些特性將在后續文章中詳細探討。

7. 版本演進與選擇建議

  • 預覽特性轉正時間

    • Java 15:文本塊轉正
    • Java 16:Records和instanceof模式匹配轉正
  • 版本選擇建議

    對于新項目,推薦采用Java 17(LTS)作為基線版本,它可以獲得所有轉正特性,同時享受長期支持。生產環境中使用預覽特性需謹慎評估。

8. 結語

Java 14通過引入開關表達式、記錄類型、文本塊、instanceof的模式匹配和更有幫助的NullPointerException等特性,顯著提升了代碼的簡潔性、可讀性和調試效率。這些特性是Java語言現代化的重要里程碑,幫助開發者更高效地編寫高質量代碼。

參考資料

  • Oracle Java 14 Release Notes
  • OpenJDK JEP Index
  • Happy Coders - Java Records
  • Baeldung - Java 14 New Features
  • Happy Coders - Java Text Blocks
  • Pattern Matching for instanceof
  • Helpful NullPointerExceptions

希望本文能為您提供深入的見解和實用的代碼示例!如果您有任何問題或建議,歡迎留言討論。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93674.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93674.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93674.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在虛擬機ubuntu上修改framebuffer桌面不能顯示圖像

目錄 一、測試程序 二、排查原因 三、為什么 Xorg 會導致程序無法工作&#xff1f; 一、測試程序 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #in…

語言模型的評估指標整理

語言模型&#xff08;Language Models&#xff09;是自然語言處理&#xff08;NLP&#xff09;的核心組件&#xff0c;廣泛應用于機器翻譯、文本生成、對話系統等領域。隨著模型復雜度的提升&#xff0c;如何科學、系統地評估模型性能變得至關重要。評估指標不僅幫助我們理解模…

【開發技術】.Net中配置Serilog日志分級記錄

目錄 一、目的 二、解決方案 2.1 下載serilog包 2.2 Serilog配置 2.2.1 使用多個File sink配置不同的最小日志級別 2.2.2 使用Filter條件分流到不同文件 三、使用建議 四、文章總結 一、目的 在日常開發中&#xff0c;需要根據不同的場景去記錄日志&#xff0c;根據實際…

聊聊如何判斷發現的缺陷屬于前后端

目錄 一、觀察缺陷現象 二、檢查網絡請求&#xff08;核心方法&#xff09; 三、模擬請求驗證后端 四、查看日志 五、數據流分析 六、判斷前后端缺陷方法 判斷發現的缺陷是前后端&#xff0c;可以通過觀察缺陷現象&#xff0c;檢查網絡請求&#xff0c;查看后端日志&…

Python3與MySQL的PyMySQL連接與應用

Python3與MySQL的PyMySQL連接與應用 引言 隨著互聯網技術的飛速發展,數據庫在各個領域的應用日益廣泛。MySQL作為一種開源的關系型數據庫管理系統,因其穩定性和高效性,被廣泛應用于各種場景。Python作為一種高級編程語言,以其簡潔、易讀、易學等特點,受到了廣大開發者的…

智慧城市SaaS平臺|市政公用管理系統

【道路監測運維系統】1.數據可視化a) 實時監控支持對道路監測數據進行分析評估&#xff0c;為道路養護、交通管理、環境保護等提供數據支撐2.道路基礎設施監測支持對道路基礎設施的運行狀態進行實時監測&#xff0c;包括路面狀況3.交通流量監測支持對道路交通流量進行實時監測&…

Maven 配置阿里云鏡像加速

Maven 配置阿里云鏡像加速&#xff1a; 完整配置步驟&#xff08;Windows 系統&#xff09; 1. 找到 Maven 的 settings.xml 文件 全局配置&#xff1a;D:\software\apache-maven-3.9.11\conf\settings.xml用戶配置&#xff1a;C:\Users\Admin\.m2\settings.xml&#xff08;推薦…

去除視頻字幕 3 : 繼續研究 IOPaint,記錄幾個問題

1. 為什么單獨運行&#xff0c;效果很好&#xff0c;批量運行&#xff0c;效果很差。 1. 我運行 iopaint start --modellama --devicecuda --port8080在瀏覽器中單獨選擇圖片&#xff0c;涂選區域&#xff0c;然后處理&#xff0c;此時的效果非常好。2. 但是我進行 iopaint ru…

【深度之眼機器學習筆記】04-01-決策樹簡介、熵,04-02-條件熵及計算舉例,04-03-信息增益、ID3算法

1. 決策樹與熵 1.1 決策樹簡介 下面有一個貸申請樣本表&#xff0c;有許多特征 我們根據特征數據生成一棵樹&#xff0c;比如年齡有青年&#xff0c;中年&#xff0c;老年三個類別&#xff0c;那么就有三個分支&#xff0c;分別對應著三種類別。如果是青年那么就看工作&#xf…

八股文場景題

如何預估接口上線后的 QPS 問題引入 這個問題其實是一個非常實際的問題&#xff0c;因為我們在開發需求后&#xff0c;例如&#xff1a;新增了一個接口 有一個步驟是值得做的&#xff0c;那就是預估這個接口的QPS 因為我們是可以去調配對應服務器的數量和運行配置的 例如我…

【Web安全】深入淺出理解“SQL注入-偽靜態注入”及空格限制繞過技巧

文章目錄什么是偽靜態注入&#xff1f;偽靜態注入中如何繞過空格限制&#xff1f;1. 用注釋符替代空格2. 用不可見字符&#xff08;URL 編碼&#xff09;替代3. 用括號分隔語句4. 用特殊符號替代核心邏輯往期文章【Web安全】一次性搞懂 ReDOS 漏洞原理/檢測/防御 【Web安全】一…

【讀論文】Step-Audio 2 深度解讀:邁向工業級語音交互的「全能型選手」

引言:step-Audio升級 語音交互技術,作為人機交互最自然、最直接的方式之一,正以前所未有的速度發展。從簡單的語音指令到流暢的語音對話,我們對 AI 的期望越來越高。然而,要讓 AI 真正成為我們的“知心伙伴”,僅僅能“聽懂”和“說出”還遠遠不夠。 一個理想的語音 AI,…

java web 重定向

目錄結構 demo\day20\src\com\demo\service\Dome1.javademo\day20\src\com\demo\service\Dome2.javademo\day20\src\com\demo\service\Dome3.javademo\day20\src\com\demo\service\Dome4.javademo\day20\web\WEB-INF\lib\javax.servlet.jardemo\day20\web\index.jspdemo\day20\…

MySQL(配置)——MariaDB使用

一、簡介 MariaDB 和 MySQL 作為兩個流行的關系型數據庫管理系統&#xff0c;它們的區別可以從多個角度來探討。盡管 MariaDB 最初是 MySQL 的一個分支&#xff0c;但隨著時間的推移&#xff0c;它們逐漸在功能、性能和開發方向上有所不同。MariaDB 是 MySQL 的一個分支&#x…

Web3:賽道劃分與發展趨勢解析

區塊鏈技術現在已經從單一的加密貨幣支付系統發展為涵蓋金融、藝術、組織治理和社區文化的多元生態系統。這次我們將深入解析 DeFi&#xff08;去中心化金融&#xff09;、NFT&#xff08;非同質化代幣&#xff09;、DAO&#xff08;去中心化自治組織&#xff09;與 MEME&#…

LeetCode 283 - 移動零

思路 使用雙指針法&#xff0c;一次遍歷完成原地修改。 慢指針 slow&#xff1a;指向下一個非零元素應該被放置的位置。快指針 fast&#xff1a;遍歷整個數組&#xff0c;尋找非零元素。 當 fast 遇到非零數時&#xff0c;將其值賦給 slow 指向的位置&#xff0c;然后 slow 前進…

8. 網絡層

在復雜的網絡環境中確定一個合適的路徑.1. IP協議1. 基本概念IP協議&#xff1a;提供一種能力(有非常大的概率&#xff0c;做到某事)&#xff0c;把數據報從主機A&#xff0c;跨網絡&#xff0c;送到主機B --> 必須要有方式&#xff0c;標識通信兩端唯一性&#xff01;&…

【通識】線性代數(Linear Algebra)

線性代數被廣泛應用于抽象代數和泛函分析中&#xff1b;通過解析幾何&#xff0c;線性代數能被具體表示&#xff0c;線性代數被泛化為算子理論。而非線性模型被近似為線性模型&#xff0c;應用場景多為自然科學和社會科學。 費馬和笛卡爾的工作&#xff0c;線性代數出現于十七世…

Qt 嵌入式界面優化技術

在嵌入式系統中&#xff0c;界面性能直接影響用戶體驗和系統穩定性。由于嵌入式設備通常資源受限&#xff08;如低性能 CPU、有限內存、小尺寸屏幕&#xff09;&#xff0c;需針對性優化 Qt 界面以實現流暢顯示和高效交互。本文從渲染引擎、資源管理、布局優化到硬件加速&#…

去除視頻字幕 4 : 下一步,打算研究 Video Inpainting (視頻修復):

就是說&#xff0c;到現在&#xff0c;才算是真正開始&#xff0c;才發現真正的問題。 嘗試去除視頻上的字幕&#xff0c;使用 IOPaint, 效果很初級。。。問題描述 請幫我分析此時的效果。 此時的右側字幕區域&#xff0c;閃爍不停&#xff01;我原本以為效果會很好。實際非常…