<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 13 新功能介紹

          共 12306字,需瀏覽 25分鐘

           ·

          2021-08-10 18:17

          Java 13 by Alena Penkova

          自從 Oracle 調(diào)整了 Java 的版本發(fā)布節(jié)奏之后,Java 版本發(fā)布越來越快,雖然都說 Java 版本任他發(fā),我用 Java 8,不過新版本的 Java 功能還是要學(xué)習(xí)一下的。

          Java 13 早在 2019 年 9 月就已經(jīng)發(fā)布,雖然不是長久支持版本,但是也帶來了不少新功能。

          Java 13 官方下載:https://jdk.java.net/archive/

          Java 13 官方文檔:http://openjdk.java.net/projects/jdk/13/

          Java 13 新功能

          1. JEP 350: 動態(tài) CDS 存檔
          2. JEP 351: ZGC,歸還未使用的內(nèi)存 (實驗性)
          3. JEP 353: 重新實現(xiàn) Socket API
          4. JEP 354: Switch 表達式 (二次預(yù)覽)
          5. JEP 355: 文本塊 (預(yù)覽)

          擴展:此文章屬于 Java 新特性教程 系列,會介紹 Java 每個版本的新功能,可以點擊瀏覽。

          1. JEP 350 動態(tài) CDS 存檔

          JVM 啟動時有一步是需要在內(nèi)存中加載類,而如果有多個 jar,加載第一個 jar 的速度是最慢的。這就延長了程序的啟動時間,為了減少這個時間,Java 10 引入了應(yīng)用程序類數(shù)據(jù)共享(CDS)機制,它可以把你想共享的類共享在程序之間,使不同的 Java 進程之間共享這個類來減少這個類占用的空間以及加載速度。不過 Java 10 中使用這個功能的步驟比較繁瑣。

          擴展閱讀:Java 10 新功能介紹

          而 Java 13 中的 AppCDS,允許 Java 應(yīng)用在程序執(zhí)行結(jié)束時(如果 JVM 沒有崩潰)進行動態(tài)存檔;存儲的內(nèi)容包括所有加載的應(yīng)用類型類和使用的類庫,這些存儲的類庫本來并不存在于默認的 CDS 存檔中。

          使用這個功能非常簡單,只需要在程序啟動時增加啟動參數(shù) 。

          # ArchiveClassesAtExit,程序結(jié)束時動態(tài)存檔
          bin/java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello
          # SharedArchiveFile,使用指定存檔啟動
          bin/java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello

          2. JEP 351: ZGC,歸還未使用的內(nèi)存 (實驗性)

          在 Java 13 之前,ZGC 雖然在清理內(nèi)存時導(dǎo)致的停頓時間非常少,但是即使內(nèi)存已經(jīng)長時間沒有使用,ZGC 也不會將內(nèi)存返還給操作系統(tǒng),這對那些十分關(guān)注內(nèi)存占用的應(yīng)用程序非常不友好。

          比如:

          • 資源按使用量付費的云上容器環(huán)境。

          • 應(yīng)用雖然長時間閑置,但是占用了內(nèi)存,導(dǎo)致運行的其他程序內(nèi)存緊張。

          而新增的這個功能,可以讓 ZGC 歸還長時間沒有使用的內(nèi)存給操作系統(tǒng),這對某些用戶來說十分友好。

          3. JEP 353: 重新實現(xiàn) Socket API

          java.net.Socketjava.net.ServerSocket 類早在 Java 1.0 時就已經(jīng)引入了,它們的實現(xiàn)的 Java 代碼和 C 語言代碼的混合,維護和調(diào)試都十分不易;而且這個實現(xiàn)還存在并發(fā)問題,有時候排查起來也很困難。

          因此,在 Java 13 中引入了新的實現(xiàn)方式,使用了新的實現(xiàn) NioSocketImpl 來代替老舊的 PlainSocketImpl 實現(xiàn)。雖然功能相同,但是老的方式在當(dāng)前以及未來幾個版本內(nèi)不會刪除,用戶隨時可以通過 -Djdk.net.usePlainSocketImpl 參數(shù)切換回老的實現(xiàn)方式,以兼容意外情況。

          編寫一個測試類可以發(fā)現(xiàn)這個變化。

          import java.io.IOException;
          import java.net.ServerSocket;
          import java.net.Socket;
          public class Test {
              public static void main(String[] args) {
                  try (ServerSocket serverSocket = new ServerSocket(8000)){
                      boolean running = true;
                      while(running){
                          Socket clientSocket = serverSocket.accept();
                          //do something with clientSocket
                      }
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }

          使用 Java 13 運行,通過參數(shù) -XX:+TraceClassLoading 追蹤加載的類,日志中可以看到 NioSocketImpl

          ?  develop ./jdk-13.0.2.jdk/Contents/Home/bin/java -XX:+TraceClassLoading Test.java | grep SocketImpl
          [0.699s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
          [0.699s][info   ][class,load] java.net.SocketImpl$$Lambda$173/0x0000000800c37440 source: java.net.SocketImpl
          [0.702s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
          [0.702s][info   ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base
          [0.713s][info   ][class,load] sun.nio.ch.NioSocketImpl$FileDescriptorCloser source: jrt:/java.base

          但在 Java 12 并不是 NioSocketImpl

          ?  develop ./jdk-12.0.2.jdk/Contents/Home/bin/java -XX:+TraceClassLoading Test.java | grep SocketImpl
          [0.665s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
          [0.665s][info   ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base
          [0.665s][info   ][class,load] java.net.PlainSocketImpl source: jrt:/java.base
          [0.665s][info   ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
          [0.666s][info   ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:/java.base

          4. JEP 354: Switch 表達式 (二次預(yù)覽)

          你為什么不愿意使用使用 switch 表達式?我想其中一個原因應(yīng)該是, switch 表達式的代碼不夠美觀優(yōu)雅,甚至有些啰嗦。比如像下面的例子。

          package com.wdbyte;

          public class Java13Switch {
              public static void main(String[] args) {
                //通過傳入月份,輸出月份所屬的季節(jié)
                System.out.println(switchJava12Before("march"));
              }
              public static String switchJava12Before(String month) {
                  String reuslt = null;
                  switch (month) {
                      case "march":
                      case "april":
                      case "may":
                          reuslt = "春天";
                          break;
                      case "june":
                      case "july":
                      case "august":
                          reuslt = "夏天";
                          break;
                      case "september":
                      case "october":
                      case "november":
                          reuslt = "秋天";
                          break;
                      case "december":
                      case "january":
                      case "february":
                          reuslt = "冬天";
                          break;
                  }
                  return reuslt;
              }
          }

          而在 Java 12 中,已經(jīng)對 switch 進行了改進,使之可以使用 cast L -> 表達式進行操作,且可以具有返回值,這樣代碼就更加美觀使用了,不過這在 Java 12 中是一個預(yù)覽功能。

          // 通過傳入月份,輸出月份所屬的季節(jié)
          public static String switchJava12(String month) {
               return switch (month) {
                  case "march""april""may"            -> "春天";
                  case "june""july""august"           -> "夏天";
                  case "september""october""november" -> "秋天";
                  case "december""january""february"  -> "冬天";
                  default -> "month erro";
              };
          }

          擴展閱讀:Java 12 新特性介紹

          而現(xiàn)在,在 Java 13 中,又對 switch 表達式進行了增強,增加了yield 關(guān)鍵詞用于返回值,相比 break ,語義更加明確了。

          public static String switchJava13(String month) {
              return switch (month) {
                  case "march""april""may":
                      yield "春天";
                  case "june""july""august":
                      yield "夏天";
                  case "september""october""november":
                      yield "秋天";
                  case "december""january""february":
                      yield "冬天";
                  default:
                      yield "month error";
              };
          }

          5. JEP 355: 文本塊 (預(yù)覽)

          在這之前,如果我們把一個 JSON 賦值給字符串:

          String content = "{\n"
              + "    \"upperSummary\": null,\n"
              + "    \"sensitiveTypeList\": null,\n"
              + "    \"gmtModified\": \"2011-08-05 10:50:09\",\n"
              + "    \"lowerGraph\": null,\n"
              + "    \"signature\": \"\",\n"
              + "    \"appName\": \"xxx\",\n"
              + "    \"lowerSummary\": null,\n"
              + "    \"gmtCreate\": \"2011-08-05 10:50:09\",\n"
              + "    \"type\": \"CALL\",\n"
              + "    \"name\": \"xxxx\",\n"
              + "    \"subType\": \"yyy\",\n"
              + "    \"id\": 1,\n"
              + "    \"projectId\": 1,\n"
              + "    \"status\": 1\n"
              + "}";

          終于不用寫丑陋的長字符串了,從 Java 13 開始你可以使用文本塊的方式定義字符串了。

          String content2 = """
                  {
                  "
          upperSummary": null,
                  "
          sensitiveTypeList": null,
                  "
          gmtModified": "2011-08-05 10:50:09",
                  "
          lowerGraph": null,
                  "
          signature": "",
                  "
          appName": "xxx",
                  "
          lowerSummary": null,
                  "
          gmtCreate": "2011-08-05 10:50:09",
                  "
          type": "CALL",
                  "
          name": "xxxx",
                  "
          subType": "yyy",
                  "
          id": 1,
                  "
          projectId": 1,
                  "
          status": 1
              }
                           "
          "";

          不過這是一個預(yù)覽功能,如果你要是在 Java 13 中使用需要手動開啟預(yù)覽功能,這個功能在 Java 15 中正式發(fā)布。

          如果你想嘗試,可以去下載最新版了,玩的開心。

          參考

          1. http://openjdk.java.net/projects/jdk/13/
          2. https://nipafx.dev/java-application-class-data-sharing/
          3. https://www.wdbyte.com/2020/02/jdk/jdk12-feature/
          4. https://mkyong.com/java/what-is-new-in-java-13/

          相關(guān)文章

          1. Java 8 Predicate 函數(shù)接口
          2. Java 8 Function 函數(shù)接口
          3. Java 12 新特性介紹
          4. 最通俗易懂的 Java 10 新特性講解

          瀏覽 67
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕在线观看国产 | 无码肉厚美臂小早川怜子 | 免费看黄色视频的网站 | 99国产香蕉 | 可以看的亚洲黄片视频 |