AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

要不要升級?Java 21強大的新特性,代碼量減半

來源: 責編: 時間:2024-05-16 09:09:13 124觀看
導讀1. record模式Record模式由 JEP 405 作為預覽功能提出,并在 JDK 19 中發布,JEP 432 進行了第二次預覽,并在 JDK 20 中發布。該功能與用于switch的模式匹配(JEP 441)共同發展,兩者之間有相當多的交互1.1 instanceof類型模式O

1. record模式

Record模式由 JEP 405 作為預覽功能提出,并在 JDK 19 中發布,JEP 432 進行了第二次預覽,并在 JDK 20 中發布。該功能與用于switch的模式匹配(JEP 441)共同發展,兩者之間有相當多的交互Aa628資訊網——每日最新資訊28at.com

1.1 instanceof類型模式

Object obj = "Pack" ;// Java 16之前if (obj instanceof String) {    String s = (String) obj ;    System.out.println("強轉為String") ;}// 自Java 16起if (obj instanceof String s) {    System.out.println("簡便多了") ;}

在上面的代碼中從java16開始,運行時obj的值是String的實例,則obj與類型模式String s匹配。如果模式匹配,則表達式的實例為true,并且模式變量s初始化為obj轉換為String的值,然后可以在包含的代碼塊中使用該值。Aa628資訊網——每日最新資訊28at.com

1.2 模式匹配與Records

Records (JEP 395)是數據的透明載體。接收record類實例的代碼通常將使用內置的組件訪問器方法提取數據,稱為組件。例如,我們可以使用類型模式來測試值是否是record類Point的實例,如果是,則從值中提取x和y組件:Aa628資訊網——每日最新資訊28at.com

// 自Java 16起public record Point(int x, int y) {}public static void main(String[] args) {  Object obj = new Point(10, 20);  if (obj instanceof Point p) {    int x = p.x();    int y = p.y();    System.out.println(x + y);  }}

上面的代碼看著與1.1中介紹的沒撒區別就是類型模式,在上面的代碼中我們僅僅是訪問了record類x與y的方法,如果是這樣我們還可以像下面這樣操作:Aa628資訊網——每日最新資訊28at.com

Object obj = new Point(10, 20) ;// 自java 21起if (obj instanceof Point(int x, int y)) {  System.out.println(x + y) ;}

這里的Point(int x, int y) 是一個record模式。它將提取組件的局部變量聲明移至模式本身,并在值與模式匹配時通過調用訪問器方法初始化這些變量。Aa628資訊網——每日最新資訊28at.com

1.3 嵌套record模式

有如下定義Aa628資訊網——每日最新資訊28at.com

public record Point(int x, int y) {}enum Color { RED, GREEN, BLUE }record ColoredPoint(Point p, Color c) {}record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {}

如果要提取左上角點的顏色,我們可以這樣寫:Aa628資訊網——每日最新資訊28at.com

Object r = new Rectangle(    new ColoredPoint(new Point(0, 0), Color.RED),     new ColoredPoint(new Point(100, 100), Color.BLUE)  ) ;// 從java 21起  if (r instanceof Rectangle(ColoredPoint ul, ColoredPoint lr)) {  System.out.printf("%s, %s%n", ul, lr) ;}

輸出結果Aa628資訊網——每日最新資訊28at.com

ColoredPoint[p=Point[x=0, y=0], c=RED], ColoredPoint[p=Point[x=100, y=100], c=BLUE]

如果你希望訪問具體的顏色值,record模式還支持嵌套,如下示例:Aa628資訊網——每日最新資訊28at.com

// 從java 21起if (r instanceof Rectangle(    ColoredPoint(Point(int x, int y), Color c1),     ColoredPoint lr  )) {  System.out.printf("x = %d, y = %d%n", x, y) ;}

1.4 嵌套模式無法匹配情況

在下面這情況下是無法進行匹配的Aa628資訊網——每日最新資訊28at.com

public record Pair(Object x, Object y) {}Pair p = new Pair(42, 42);if (p instanceof Pair(String s, String t)) {  System.out.println(s + ", " + t);} else {  System.out.println("Not a pair of strings") ;}

以上是關于record 模式的所有內容。Aa628資訊網——每日最新資訊28at.com

2. switch模式匹配

該功能最初由 JEP 406(JDK 17)提出,后經 JEP 420(JDK 18)、427(JDK 19)和 433(JDK 20)改進。它與 "1. record模式 "功能(JEP 440)共同發展。Aa628資訊網——每日最新資訊28at.com

先來看下如下這段代碼Aa628資訊網——每日最新資訊28at.com

Object obj = 100L ;if (obj instanceof Integer) {  Integer i = (Integer) obj ;  obj = String.format("int %d", i);} else if (obj instanceof Long) {  Long l = (Long) obj ;  obj = String.format("long %d", l);} else if (obj instanceof String) {  String s = (String) obj ;  obj = String.format("String %s", s);}

有個instanceof 模式以后就可以簡化這樣了Aa628資訊網——每日最新資訊28at.com

Object obj = 100L ;if (obj instanceof Integer i) {  obj = String.format("int %d", i);} else if (obj instanceof Long l) {  obj = String.format("long %d", l);} else if (obj instanceof String s) {  obj = String.format("String %s", s);}System.out.printf("result obj = %s%n", obj) ;

注意:上面的代碼有2個問題Aa628資訊網——每日最新資訊28at.com

  1. 上面的代碼有如果沒有編譯器的作用,那么它的時間復雜度將是O(n)
  2. 隱藏了一個BUG,當if,else沒有判斷到某個類型時可能會出現問題上面的代碼并沒有else,因為不強制所以當判斷遺漏了某種類型時可能會給程序帶來潛在的問題。

從Java 21開始,我們可以如下處理上面的if.. else Aa628資訊網——每日最新資訊28at.com

var ret = switch (obj) {  case Integer i -> String.format("int %d", i);  case Long l    -> String.format("long %d", l);  case String s  -> String.format("String %s", s);  default        -> obj.toString() ;};System.out.printf("result ret = %s%n", ret) ;

在過去我們知道如果switch的每個case沒有break或者return,那么它會穿透到下一個case直到遇到break或return。并且在傳統的switch中沒有default也是可以的。但是在上面的代碼中必須要有default子句。Aa628資訊網——每日最新資訊28at.com

2.1 switch與null值

傳統上,如果switch表達式值為空,switch 語句和表達式會拋出 NullPointerException,因此必須在 switch 之外進行空判斷:Aa628資訊網——每日最新資訊28at.com

String s = null ;switch (s) {  // 如果不清楚這里的語法,你應該先看看java14對switch新語法的介紹  case "a", "b" -> System.out.println("a or b") ;  default -> System.out.println("defualt value") ;}

控制臺輸出Aa628資訊網——每日最新資訊28at.com

圖片圖片Aa628資訊網——每日最新資訊28at.com

在上面的代碼中在過去,我們要先對s進行null的判斷,再進行switch,否則有可能就會出現上面的錯誤。修改如下:Aa628資訊網——每日最新資訊28at.com

if (s == null) {  return ;}switch (s) {  // TODO}

以上代碼是Java 21之前,從Java 21起,我們可以如下:Aa628資訊網——每日最新資訊28at.com

switch (s) {  case null -> System.out.println("oops") ;  case "a", "b" -> System.out.println("a or b") ;  default -> System.out.println("defualt value") ;}

無需單獨的if判斷是否為null情況。Aa628資訊網——每日最新資訊28at.com

2.2 switch條件判斷

在case中還可以添加if...else判斷Aa628資訊網——每日最新資訊28at.com

static void fn1(String resp) {  switch (resp) {    case String s -> {      if (s.equalsIgnoreCase("success"))        System.out.println("處理成功");      else if (s.equalsIgnoreCase("failure"))        System.err.println("處理失敗");      else        System.out.println("未知結果") ;    }  }}

在case中是使用when子句Aa628資訊網——每日最新資訊28at.com

static void fn2(String resp) {  switch (resp) {    case null -> {}    case String s     when s.equalsIgnoreCase("success") -> {      System.out.println("處理成功");    }    case String s    when s.equalsIgnoreCase("failure") -> {      System.err.println("處理失敗");    }    case String s -> {        System.out.println("未知結果") ;    }  }}

這樣,switch的可讀性就更強了。Aa628資訊網——每日最新資訊28at.com

2.3 switch與enum常量

在Java 21之前,switch的case表達式必須是枚舉類型,標簽必須是枚舉常量的簡單名稱,如下示例:Aa628資訊網——每日最新資訊28at.com

public enum Color { RED, BLUE, GREEN }public static void fn1(Color c) {  switch (c) {    case RED, BLUE -> System.out.println("我喜歡的顏色") ;    case GREEN -> {      // TODO    }    default -> System.out.println("我討厭的顏色") ;  }}

上面說的標簽必須是枚舉常量的簡單名稱什么意思呢?就是說在java21之前使用枚舉時的標簽不能是下面這種寫法:Aa628資訊網——每日最新資訊28at.com

case Color.GREEN -> {}

而從Java 21起可以使用這種語法。Aa628資訊網——每日最新資訊28at.com

3. 虛擬線程

關于虛擬線程請查看這篇文章:Aa628資訊網——每日最新資訊28at.com

【技術革命】JDK21虛擬線程來襲,讓系統的吞吐量翻倍!Aa628資訊網——每日最新資訊28at.com

4. 字符串模版

注:這是一個預覽功能Aa628資訊網——每日最新資訊28at.com

Aa628資訊網——每日最新資訊28at.com

編譯:javac --enable-preview --source 21 -Xlint:preview Xxx.javaAa628資訊網——每日最新資訊28at.com

運行:java --enable-preview XxxAa628資訊網——每日最新資訊28at.com

Aa628資訊網——每日最新資訊28at.com

在開發中字符串相關的操作是非常非常多的,雖然Java 提供了多種字符串組成機制,但遺憾的是,所有機制都有缺點。Aa628資訊網——每日最新資訊28at.com

  • 使用+操作符拼接字符串,看著都不好理解
String result = x + " + " + y + " = " + (x + y) ;
  • 冗余的StringBuilder
String s = new StringBuilder().append(x).append(" + ")  .append(y).append(" = ").append(x + y).toString() ;
  • String#format 與 String#formatted將格式字符串與參數分離,避免了類型錯配:
int x = 10, y = 20 ;String s = String.format("%2$d + %1$d = %3$d", x, y, x + y);String t = "%2$d + %1$d = %3$d".formatted(x, y, x + y) ;
  • java.text.MessageFormat要求太多,而且格式字符串中使用了不熟悉的語法:
String ret = MessageFormat.format("{0} + {1} = {2}", x, y, x + y) ;

4.1 STR 模板處理器

STR 是 Java 平臺定義的模板處理器。它通過用表達式的(字符串化)值替換模板中的每個嵌入表達式來執行字符串插值。Aa628資訊網——每日最新資訊28at.com

String firstName = "Bill" ;String lastName  = "Duck" ;String fullName  = STR."/{firstName} /{lastName}" ;System.out.println(fullName) ;

輸出結果Aa628資訊網——每日最新資訊28at.com

Bill Duck

注:STR 是一個公共靜態最終字段,會自動導入到每個 Java 源文件中。Aa628資訊網——每日最新資訊28at.com

表達式還可以執行相應的操作,如下:Aa628資訊網——每日最新資訊28at.com

int x = 10, y = 20 ;String result = STR."/{x} + /{y} = /{x + y}" ;System.out.println(result) ;// 10 + 20 = 30

表達式中還可以調用方法Aa628資訊網——每日最新資訊28at.com

static String getName() {  return "張三" ;}static record Req(String date, String time) {}static void fn5() {  String s = STR."我的名字是 /{getName()} ";  System.out.println(s) ;  Req req = new Req("2000-01-01", "23:59:59") ;  String t = STR."Access at /{req.date} /{req.time}";  System.out.println(t) ;}

輸出結果Aa628資訊網——每日最新資訊28at.com

我的名字是 張三Access at 2000-01-01 23:59:59

多行模版字符串Aa628資訊網——每日最新資訊28at.com

static void fn6() {  String name    = "張三";  String phone   = "1899999999";  String address = "xxxooo";  String json = STR."""  {    "name":    "/{name}",    "phone":   "/{phone}",    "address": "/{address}"  }  """;  System.out.println(json);}

輸出結果Aa628資訊網——每日最新資訊28at.com

{   "name": "張三",   "phone": "1899999999",   "address": "xxxooo"}

以上是基于STR模版處理器的內容,接下來介紹另外一個。Aa628資訊網——每日最新資訊28at.com

4.2 FMT 模板處理器

FMT 是 Java 平臺定義的另一種模板處理器。FMT 與 STR 類似,它執行插值,但也解釋嵌入式表達式左側的格式規范。格式說明符與 java.util.Formatter 中定義的格式說明符相同。Aa628資訊網——每日最新資訊28at.com

record Rectangle(String name, double width, double height) {  double area() {    return width * height;  }}public static void main(String[] args) {  Rectangle[] zone = new Rectangle[] {    new Rectangle("Alfa", 17.8, 31.4),    new Rectangle("Bravo", 9.6, 12.4),  };  String s = FMT."""    Description     Width    Height     Area    %-12s/{zone[0].name}  %7.2f/{zone[0].width}  %7.2f/{zone[0].height}     %7.2f/{zone[0].area()}    %-12s/{zone[1].name}  %7.2f/{zone[1].width}  %7.2f/{zone[1].height}     %7.2f/{zone[1].area()}    /{" ".repeat(28)} Total %7.2f/{zone[0].area() + zone[1].area() + zone[2].area()}  """;  System.out.println(s) ;}

5. 序列集合

在Java21 之前的集合類中要獲取第一個和最后一個元素,不同的集合操作方式不同或者壓根就沒有對應的方法。如下示例:Aa628資訊網——每日最新資訊28at.com

圖片圖片Aa628資訊網——每日最新資訊28at.com

在說遍歷集合,正向時(從第一個到最后一個)操作方法基本一致。但是反向時遍歷時每個集合就又不相同了。Aa628資訊網——每日最新資訊28at.com

在JDK21中提供了如下3個序列接口:Aa628資訊網——每日最新資訊28at.com

  • SequencedCollection
public interface SequencedCollection<E> extends Collection<E> {  SequencedCollection<E> reversed() ;  default void addFirst(E e) ;  default void addLast(E e) ;  default E getFirst() ;  default E getLast() ;  default E removeFirst() ;  default E removeLast() ;}
  • SequencedSet
public interface SequencedSet<E> extends SequencedCollection<E>, Set<E> {  SequencedSet<E> reversed();}
  • SequencedMap
public interface SequencedMap<K, V> extends Map<K, V> {  SequencedMap<K, V> reversed() ;  default Map.Entry<K,V> firstEntry() ;  default Map.Entry<K,V> lastEntry() ;  default Map.Entry<K,V> pollFirstEntry() ;  default Map.Entry<K,V> pollLastEntry() ;  default V putFirst(K k, V v) ;  default V putLast(K k, V v) ;  // other}

以上3個集合都提供了對應的獲取第一個和最后一個元素的方法及集合反轉方法。上面定義的三個新接口與現有的集合類型層次結構非常吻合,如下圖:Aa628資訊網——每日最新資訊28at.com

圖片圖片Aa628資訊網——每日最新資訊28at.com

對現有的類和接口進行了如下調整:Aa628資訊網——每日最新資訊28at.com

  • List 現在將 SequencedCollection 作為其直接超接口、
  • Deque 現在將 SequencedCollection 作為其直接超接口、
  • LinkedHashSet 進一步實現了 SequencedSet、
  • SortedSet 現在將 SequencedSet 作為其直接超接口、
  • LinkedHashMap 進一步實現了 SequencedMap,而
  • SortedMap 現在將 SequencedMap 作為其直接超接口。

6. 未命名模式&變量

注:這是一個預覽功能Aa628資訊網——每日最新資訊28at.com

先看下面這個示例Aa628資訊網——每日最新資訊28at.com

public record Point(int x, int y) {}enum Color { RED, GREEN, BLUE }record ColoredPoint(Point p, Color c) {}record Rectangle(ColoredPoint cp) {}  Object obj = new Rectangle(    new ColoredPoint(new Point(10, 10), Color.RED)  ) ;if (obj instanceof Rectangle(ColoredPoint(Point(int x, int y), Color c))) {  System.out.printf("x = %d, y = %d%n", x, y) ;}

在上面的if判斷中,對于Color c變量并沒有使用,從Java 21開始我們可以像下面這樣改寫:Aa628資訊網——每日最新資訊28at.com

if (obj instanceof Rectangle(ColoredPoint(Point(int x, int y), _))) {  System.out.printf("x = %d, y = %d%n", x, y) ;}

使用一個 "_" 下劃線代替即可。Aa628資訊網——每日最新資訊28at.com

未使用的變量Aa628資訊網——每日最新資訊28at.com

int[] arr = {1, 2, 3, 4, 5} ;int total = 0 ;for (var a : arr) {  total++ ;}

在這個示例中,變量a并沒有使用,所以從Java 21開始可以改寫如下:Aa628資訊網——每日最新資訊28at.com

for (var _ : arr) {  total++ ;}

對于這樣沒有使用的變量,我們可以用一個 "_" 下劃線代替。其它示例:Aa628資訊網——每日最新資訊28at.com

try {  int a = 1 / 0 ;} catch (Exception _) { // 這里沒有用到異常通過可以使用 _}

注:我用的Eclipse沒法直接使用,我這里是通過記事本編寫,通過命令行編譯&運行。Aa628資訊網——每日最新資訊28at.com

7. 未命名的類&Main方法Aa628資訊網——每日最新資訊28at.com

注:這是一個預覽功能Aa628資訊網——每日最新資訊28at.com

下面這個代碼是學習java的入門代碼Aa628資訊網——每日最新資訊28at.com

public class UnnamedClassAndMain { public static void main(String[] args) {   System.out.println("Hello World!!!") ; }}

從Java 21開始,我們可以簡化成如下形式了Aa628資訊網——每日最新資訊28at.com

public class UnnamedClassAndMain {  void main() {    System.out.println("Hello World!!!") ;  }}

未命名的類Aa628資訊網——每日最新資訊28at.com

還是拿上面的程序演示,我們還可以繼續簡化如下形式:Aa628資訊網——每日最新資訊28at.com

void main() {  System.out.println("Hello World!!!") ;}

對,文件中只有一個極簡的方法,連類的聲明都沒有了。你甚至還可以如下,定義方法,方法調用Aa628資訊網——每日最新資訊28at.com

String name = "Pack" ;String getName() {  return name ;}void main() {  System.out.println(getName()) ;}

類文件直接定義方法,聲明變量。Aa628資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-88373-0.html要不要升級?Java 21強大的新特性,代碼量減半

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Python進階:掌握15條PEP 8黃金法則

下一篇: Go 事件驅動編程:實現一個簡單的事件總線

標簽:
  • 熱門焦點
  • 帥氣純真少年!日本最帥初中生選美冠軍出爐

    日本第一帥哥初一生選美大賽冠軍現已正式出爐,冠軍是來自千葉縣的宗田悠良。日本一直熱衷于各種選美大賽,從&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 掘力計劃第 20 期:Flutter 混合開發的混亂之治

    在掘力計劃系列活動第20場,《Flutter 開發實戰詳解》作者,掘金優秀作者,Github GSY 系列目負責人戀貓的小郭分享了Flutter 混合開發的混亂之治。Flutter 基于自研的 Skia 引擎
  • 一年經驗在二線城市面試后端的經驗分享

    忠告這篇文章只適合2年內工作經驗、甚至沒有工作經驗的朋友閱讀。如果你是2年以上工作經驗,請果斷劃走,對你沒啥幫助~主人公這篇文章內容來自 「升職加薪」星球星友 的投稿,坐
  • 十個簡單但很有用的Python裝飾器

    裝飾器(Decorators)是Python中一種強大而靈活的功能,用于修改或增強函數或類的行為。裝飾器本質上是一個函數,它接受另一個函數或類作為參數,并返回一個新的函數或類。它們通常用
  • 三萬字盤點 Spring 九大核心基礎功能

    大家好,我是三友~~今天來跟大家聊一聊Spring的9大核心基礎功能。話不多說,先上目錄:圖片友情提示,本文過長,建議收藏,嘿嘿嘿!一、資源管理資源管理是Spring的一個核心的基礎功能,不
  • 三分鐘白話RocketMQ系列—— 如何發送消息

    我們知道RocketMQ主要分為消息 生產、存儲(消息堆積)、消費 三大塊領域。那接下來,我們白話一下,RocketMQ是如何發送消息的,揭秘消息生產全過程。注意,如果白話中不小心提到相關代
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 得物寵物生意「狂飆」,發力“它經濟”

    作者|花花小萌主近日,得物宣布正式上線寵物鑒別,通過得物App內的&ldquo;在線鑒別&rdquo;,可找到鑒別寵物的選項。通過上傳自家寵物的部位細節,就能收獲擁有專業資質認證的得物鑒
  • 與兆芯合作 聯想推出全新旗艦版筆記本電腦開天N7系列

    聯想與兆芯合作推出全新聯想旗艦版筆記本電腦開天 N7系列。這個系列采用兆芯KX-6640MA處理器平臺,KX-6640MA 處理器是采用了陸家嘴架構,16nm 工藝,4 核 4 線
Top