天天看點

Java SE 13 新增特性

Java SE 13 新增特性

作者:Grey

原文位址:Java SE 13 新增特性

源碼

源倉庫: Github:java_new_features

鏡像倉庫: GitCode:java_new_features

新版 Switch 使用方式

switch

語句增加了 yield 關鍵字表示傳回值,這個特性在

Java SE 13

中是預覽特性,在

Java SE 14

正式引入。代碼如下:

注:如果你用

Java SE 12

運作上述代碼,需要指定

--enable-preview

參數,如果使用 Intellij IDEA ,參考How to Enable Java Preview Features and Run Code from IntelliJ IDEA

package git.snippets.jdk13;

/**
 * switch yield功能
 * jdk13 實驗性功能
 * 到jdk14 正式使用
 * @author <a href="mailto:[email protected]">Grey</a>
 * @date 2021/11/29
 * @since 13
 */
public class SwitchYield {
    public static void main(String[] args) {
        String t = test("apple");
        System.out.println(t);
        String m = test("abc");
        System.out.println(m);
    }

    private static String test(String c) {
        return switch (c) {
            case "apple", "Apple":
                yield "蘋果";
            case "banana":
                yield "香蕉";
            default:
                yield "無法識别";
        };
    }
}
           

輸出結果

蘋果
無法識别
           

文本塊(預覽功能)

為了定義一個多行字元串,我們習慣于使用轉義序列來處理字元串中包含的換行和雙引号。例如,一個SQL語句看起來像這樣

String sql =
    "SELECT id, firstName, lastName FROM Employee\n"
        + "WHERE departmentId = \"IT\"\n"
        + "ORDER BY lastName, firstName";
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"
                + "}";
           

JDK Enhancement Proposal 355允許我們以更可讀的方式編寫這樣的字元串。

String sql = """
    SELECT id, firstName, lastName FROM Employee
    WHERE departmentId = "IT"
    ORDER BY lastName, firstName""";
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
    }
                 """;
           

文本塊在

Java SE 13

屬于預覽功能,在

Java SE 15

中正式啟用

Socket API 新實作方式

java.net.Socket 和 java.net.ServerSocket 類早在 Java 1.0 時就已經引入了,它們的實作的 Java 代碼和 C 語言代碼的混合,維護和調試都十分不易;而且這個實作還存在并發問題,有時候排查起來也很困難。

是以,在 Java 13 中引入了新的實作方式,使用了新的實作 NioSocketImpl 來代替老舊的 PlainSocketImpl 實作。使用者随時可以通過 -Djdk.net.usePlainSocketImpl 參數切換回老的實作方式,以相容意外情況。代碼如下

package git.snippets.jdk13;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 新版Socket API 使用了新的實作 NioSocketImpl 來代替老舊的 PlainSocketImpl 實作。
 * 需要增加-XX:+TraceClassLoading參數
 *
 * @author <a href="mailto:[email protected]">Grey</a>
 * @date 2022/8/20
 * @since 13
 */
public class NewSocketAPI {
    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 運作,通過參數 -XX:+TraceClassLoading 追蹤加載的類,日志中可以看到 NioSocketImpl。

[0.099s][info   ][class,load] java.util.Properties$LineReader source: shared objects file
[0.099s][info   ][class,load] java.io.FileInputStream$1 source: shared objects file
[0.100s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
[0.100s][info   ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base
[0.100s][info   ][class,load] sun.nio.ch.NativeDispatcher source: jrt:/java.base
[0.100s][info   ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base
           

但在 Java 12 并不是 NioSocketImpl。

[0.120s][info   ][class,load] java.util.concurrent.ConcurrentSkipListMap$Node source: shared objects file
[0.120s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.120s][info   ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base
[0.120s][info   ][class,load] java.net.PlainSocketImpl source: jrt:/java.base
[0.120s][info   ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
           

ZGC: 取消送出未使用的記憶體

ZGC 是 Java SE 11 中引入的一個實驗性垃圾收集器,它承諾在10毫秒或更短的時間内實作 stop-the-world 。

JDK Enhancement Proposal 351擴充了 ZGC 的功能,以便在特定時間後将未使用的堆記憶體傳回給作業系統。

使用

-XX:ZUncommitDelay

,你可以指定ZGC傳回未使用記憶體的時間,機關是秒。預設情況下,這個值是300秒。

該功能預設是啟用的,可以用

-XX:-ZUncommit

來禁用。

ZGC 将在 Java SE 15 中達到生産狀态。

動态 CDS 檔案

Java SE 10 中引入了應用類資料共享--一個允許建立所謂共享存檔檔案的功能。這個檔案包含了所使用平台的 JVM 所要求的二進制形式的應用類。該檔案通過記憶體映射的 I/O 映射到 JVM 的記憶體中。

直到現在,建立這個檔案還相對複雜。首先,我們必須在應用程式的測試運作期間轉儲一個類清單。隻有在第二步,我們才能從這個清單中生成共享檔案。

java -Xshare:off -XX:+UseAppCDS
    -XX:DumpLoadedClassList=helloworld.lst
    -cp target/helloworld.jar eu.happycoders.appcds.Main

java -Xshare:dump -XX:+UseAppCDS
    -XX:SharedClassListFile=helloworld.lst
    -XX:SharedArchiveFile=helloworld.jsa
    -cp target/helloworld.jar
           

JDK Enhancement Proposal 350簡化了這個過程。從 Java SE 13 開始,你可以指定

-XX:ArchiveClassesAtExit

參數,在應用程式執行結束時生成共享存檔。不再需要額外的參數

-Xshare:on

-XX:+UseAppCDS

了。

java -XX:ArchiveClassesAtExit=helloworld.jsa
    -cp target/helloworld.jar eu.happycoders.appcds.Main
           

建立的共享存檔也比以前小得多。因為它現在隻包含應用程式的類。

從 Java SE 13 開始,共享存檔的使用方法如下。

java -XX:SharedArchiveFile=helloworld.jsa
    -cp target/helloworld.jar eu.happycoders.appcds.Main
           

更多

Java SE 7及以後各版本新增特性

參考資料

official Java 13 Release Notes

Java 13 Features (with Examples)

Java ByteBuffer Example: How to Use flip() and compact()

Application Class-Data Sharing

Java 13 新功能介紹

本文來自部落格園,作者:Grey Zeng,轉載請注明原文連結:https://www.cnblogs.com/greyzeng/p/16607203.html