日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

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

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

來源: 責編: 時間:2024-05-16 09:09:13 143觀看
導讀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)共同發展,兩者之間有相當多的交互Irm28資訊網——每日最新資訊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的值,然后可以在包含的代碼塊中使用該值。Irm28資訊網——每日最新資訊28at.com

1.2 模式匹配與Records

Records (JEP 395)是數據的透明載體。接收record類實例的代碼通常將使用內置的組件訪問器方法提取數據,稱為組件。例如,我們可以使用類型模式來測試值是否是record類Point的實例,如果是,則從值中提取x和y組件:Irm28資訊網——每日最新資訊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的方法,如果是這樣我們還可以像下面這樣操作:Irm28資訊網——每日最新資訊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模式。它將提取組件的局部變量聲明移至模式本身,并在值與模式匹配時通過調用訪問器方法初始化這些變量。Irm28資訊網——每日最新資訊28at.com

1.3 嵌套record模式

有如下定義Irm28資訊網——每日最新資訊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) {}

如果要提取左上角點的顏色,我們可以這樣寫:Irm28資訊網——每日最新資訊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) ;}

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

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

如果你希望訪問具體的顏色值,record模式還支持嵌套,如下示例:Irm28資訊網——每日最新資訊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 嵌套模式無法匹配情況

在下面這情況下是無法進行匹配的Irm28資訊網——每日最新資訊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 模式的所有內容。Irm28資訊網——每日最新資訊28at.com

2. switch模式匹配

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

先來看下如下這段代碼Irm28資訊網——每日最新資訊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 模式以后就可以簡化這樣了Irm28資訊網——每日最新資訊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個問題Irm28資訊網——每日最新資訊28at.com

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

從Java 21開始,我們可以如下處理上面的if.. else Irm28資訊網——每日最新資訊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子句。Irm28資訊網——每日最新資訊28at.com

2.1 switch與null值

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

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

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

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

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

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

以上代碼是Java 21之前,從Java 21起,我們可以如下:Irm28資訊網——每日最新資訊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情況。Irm28資訊網——每日最新資訊28at.com

2.2 switch條件判斷

在case中還可以添加if...else判斷Irm28資訊網——每日最新資訊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子句Irm28資訊網——每日最新資訊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的可讀性就更強了。Irm28資訊網——每日最新資訊28at.com

2.3 switch與enum常量

在Java 21之前,switch的case表達式必須是枚舉類型,標簽必須是枚舉常量的簡單名稱,如下示例:Irm28資訊網——每日最新資訊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之前使用枚舉時的標簽不能是下面這種寫法:Irm28資訊網——每日最新資訊28at.com

case Color.GREEN -> {}

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

3. 虛擬線程

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

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

4. 字符串模版

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

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

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

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

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

在開發中字符串相關的操作是非常非常多的,雖然Java 提供了多種字符串組成機制,但遺憾的是,所有機制都有缺點。Irm28資訊網——每日最新資訊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 平臺定義的模板處理器。它通過用表達式的(字符串化)值替換模板中的每個嵌入表達式來執行字符串插值。Irm28資訊網——每日最新資訊28at.com

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

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

Bill Duck

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

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

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

表達式中還可以調用方法Irm28資訊網——每日最新資訊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) ;}

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

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

多行模版字符串Irm28資訊網——每日最新資訊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);}

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

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

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

4.2 FMT 模板處理器

FMT 是 Java 平臺定義的另一種模板處理器。FMT 與 STR 類似,它執行插值,但也解釋嵌入式表達式左側的格式規范。格式說明符與 java.util.Formatter 中定義的格式說明符相同。Irm28資訊網——每日最新資訊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 之前的集合類中要獲取第一個和最后一個元素,不同的集合操作方式不同或者壓根就沒有對應的方法。如下示例:Irm28資訊網——每日最新資訊28at.com

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

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

在JDK21中提供了如下3個序列接口:Irm28資訊網——每日最新資訊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個集合都提供了對應的獲取第一個和最后一個元素的方法及集合反轉方法。上面定義的三個新接口與現有的集合類型層次結構非常吻合,如下圖:Irm28資訊網——每日最新資訊28at.com

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

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

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

6. 未命名模式&變量

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

先看下面這個示例Irm28資訊網——每日最新資訊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開始我們可以像下面這樣改寫:Irm28資訊網——每日最新資訊28at.com

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

標簽:
  • 熱門焦點
  • 一加Ace2 Pro官宣:普及16G內存 引領24G

    一加官方今天繼續為本月發布的新機一加Ace2 Pro帶來預熱,公布了內存方面的信息。“淘汰 8GB ,12GB 起步,16GB 普及,24GB 引領,還有呢?#一加Ace2Pro#,2023 年 8 月,敬請期待。”同時
  • 轎車從天而降電動車主被撞身亡 超速搶道所致:現場視頻讓網友吵翻

    近日,上海青浦區法院判決轎車從天而降電動車主被撞身亡案,轎車車主被判有期徒刑一年。案件顯示當時男子駕駛轎車在上海某路段行駛,前車忽然轉彎提速超車,
  • CSS單標簽實現轉轉logo

    轉轉品牌升級后更新了全新的Logo,今天我們用純CSS來實現轉轉的新Logo,為了有一定的挑戰性,這里我們只使用一個標簽實現,將最大化的使用CSS能力完成Logo的繪制與動畫效果。新logo
  • K8S | Service服務發現

    一、背景在微服務架構中,這里以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環境或者
  • 得物效率前端微應用推進過程與思考

    一、背景效率工程隨著業務的發展,組織規模的擴大,越來越多的企業開始意識到協作效率對于企業團隊的重要性,甚至是決定其在某個行業競爭中突圍的關鍵,是企業長久生存的根本。得物
  • 梁柱接棒兩年,騰訊音樂闖出新路子

    文丨田靜 出品丨牛刀財經(niudaocaijing)7月5日,企鵝FM發布官方公告稱由于業務調整,將于9月6日正式停止運營,這意味著騰訊音樂長音頻業務走向消亡。騰訊在長音頻領域還在摸索。為
  • 蘋果、三星、惠普等暫停向印度出口筆記本和平板電腦

    集微網消息,據彭博社報道,在8月3日印度突然禁止在沒有許可證的情況下向印度進口電腦/平板及顯示器等產品后,蘋果、三星電子和惠普等大公司暫停向印度
  • DRAM存儲器10月價格下跌,NAND閃存本月價格與上月持平

    10月30日,據韓國媒體消息,自今年年初以來一直在上漲的 DRAM 存儲器的交易價格僅在本月就下跌了近 10%,此次是全年首次降價,而NAND 閃存本月價格與上月持平。市
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 道孚县| 阜阳市| 平武县| 克什克腾旗| 甘泉县| 乐安县| 娱乐| 从化市| 金阳县| 安西县| 静乐县| 施秉县| 什邡市| 乐东| 中超| 遂宁市| 海原县| 小金县| 乳源| 竹溪县| 松原市| 陆良县| 舒城县| 当阳市| 望都县| 商水县| 油尖旺区| 沛县| 宾阳县| 宜兴市| 富川| 鹰潭市| 英山县| 同江市| 海门市| 祁东县| 高陵县| 西乌| 新巴尔虎左旗| 临湘市| 石泉县|