JDK14新特性詳解

https://zh.wikipedia.org/wiki/Java%E7%89%88%E6%9C%AC%E6%AD%B7%E5%8F%B2

簡介

本次的Jdk14版本將帶來16個增強方案
在這裏插入圖片描述
除此之外,Jdk14版本修復了共1986項問題,其中大部分由Oracle工作人員完成

在這裏插入圖片描述

增強

  1. JEP 305 - Pattern Matching for instanceof (Preview)
  2. JEP 343 - Packaging Tool (Incubator)
  3. JEP 345 - NUMA-Aware Memory Allocation for G1
  4. JEP 349 - JFR Event Streaming
  5. JEP 352 - Non-Volatile Mapped Byte Buffers
  6. JEP 358 - Helpful NullPointerExceptions:
  7. JEP 359 - Records (Preview)
  8. JEP 361 - Switch Expressions
  9. JEP 362 - Deprecate the Solaris and SPARC Ports
  10. JEP 363 - Remove the Concurrent Mark Sweep (CMS) Garbage Collector
  11. JEP 364 - ZGC on macOS
  12. JEP 365 - ZGC on Windows
  13. JEP 366 - Deprecate the ParallelScavenge + SerialOld GC Combination
  14. JEP 367 - Remove the Pack200 Tools and API
  15. JEP 368 - Text Blocks (Second Preview)
  16. JEP 370 - Foreign-Memory Access API (Incubator)

環境

食用

JEP 305:instanceof的模式匹配:通過消除對通用樣板代碼的需求,提高了開發人員的生產率,並允許使用更簡潔的類型安全的代碼
在Jdk之前的版本中,使用instanceof模式匹配的時候需要手動進行強制轉換成需要的類型。在該版本中可以直接在後面跟上變量名,接下來不用強轉就能直接使用該變量

Object obj = "hello 14";
// Jdk之前版本
if (obj instanceof String) {
    String str = (String) obj;
    System.out.println("str length:" + str.length());
} else {
    System.out.println("obj not string.");
}

// Jdk14版本
if (obj instanceof String str) {
    System.out.println("str length:" + str.length());
} else {
    System.out.println("obj not string.");
}

JEP 343:打包工具:此孵化器工具爲開發人員提供了一種打包Java應用程序的方式,以便以平臺特定的格式進行分發
這些格式包括Windows上的msi和exe,MacOS上的pkg和dmg,以及Linux上的deb和rpm

JEP 345:G1的NUMA-Aware內存分配:此功能提高了非均勻內存訪問(NUMA)系統上G1垃圾收集器的整體性能
NUMA技術:https://www.ibm.com/developerworks/cn/linux/l-numa/index.html

JEP 349:JFR事件流:此功能公開了JDK Flight Recorder(JFR)數據以進行連續監視,這將簡化各種工具和應用程序對JFR數據的訪問
HotSpot VM使用JFR發出500多個數據點,除了解析日誌文件外,大多數其他方法無法使用。如果要使用數據,用戶必須開始記錄,停止記錄,將內容轉儲到磁盤,然後解析記錄文件。這對於應用程序概要分析非常有效,其中通常一次記錄至少一分鐘的數據,但不適用於監視目的。而在新特性中可以公開JFR發出的數據,用於持續監控

JEP 352:非易失性映射字節緩衝區:使用非易失性存儲器時,此功能爲JDK添加了文件映射模式
對FileChannel API進行了擴展,允許創建MappedByteBuffer實例。非易失性內存能夠持久化數據,因此可以利用該特性來改進性能

JEP 358:實用的NullPointerExceptions:通過精確描述哪個變量爲null以及其他有用信息,提高了 NullPointerExceptions的可用性。這將提高開發人員的生產率,並提高許多開發和調試工具的質量
目前該特性需要使用-XX:+ShowCodeDetailsInExceptionMessages參數開啓

String str = null;
System.out.println(str.length());

/**
 * Jdk之前版本異常輸出:
 * Exception in thread "main" java.lang.NullPointerException
 * 	at DemoNull.main(DemoNull.java:9)
 */

/**
 * Jdk14版本異常輸出:
 * Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "str" is null
 * 	at DemoNull.main(DemoNull.java:9)
 */

JEP 359:Records:此預覽功能提供了一種緊湊的語法,用於聲明保存淺層不變數據的類。從表面上看,此功能大大減少了此類中的樣板代碼,但最終目的是更好地允許將數據建模爲數據
在之前的Jdk版本中,如果我們要申明一個final實體類,需要手動寫構造器、getter、equals、hashCode、toString等方法。而現在,只需要使用record關鍵字,一行代碼即可搞定,申明之後將自動獲得一個構造器、getter、equals、hashCode、toString方法。在record申明的類中也可以定義其他構造器、方法、靜態方法和靜態屬性。record申明的類不能再用abstract修飾。record申明的類不能繼承其他的類。

/**
 * @author liujiazhong
 */
public final class Order {

    private final Long orderId;
    private final String orderCode;

    public Order(Long orderId, String orderCode) {
        this.orderId = orderId;
        this.orderCode = orderCode;
    }

    public Long getOrderId() {
        return orderId;
    }

    public String getOrderCode() {
        return orderCode;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Order)) return false;
        Order order = (Order) o;
        return Objects.equals(getOrderId(), order.getOrderId()) &&
                Objects.equals(getOrderCode(), order.getOrderCode());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getOrderId(), getOrderCode());
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderId=" + orderId +
                ", orderCode='" + orderCode + '\'' +
                '}';
    }
}

/**
 * @author liujiazhong
 */
public record RecordOrder(Long orderId, String orderCode) {
}

// 測試
Order order1 = new Order(1001L, "TEST1001");
RecordOrder order2 = new RecordOrder(1002L, "TEST1002");
System.out.println(order1);
System.out.println(order2);
System.out.println(order1.getOrderCode());
System.out.println(order2.orderCode());

// 結果
Order{orderId=1001, orderCode='TEST1001'}
RecordOrder[orderId=1002, orderCode=TEST1002]
TEST1001
TEST1002

// 可以定義其他信息
public record RecordOrder(Long orderId, String orderCode) {

    public static final String TYPE = "online";

    public RecordOrder() {
        this(1003L, "TEST1003");
    }

    public static void printType() {
        System.out.println(TYPE);
    }

    public void printOrderCode() {
        System.out.println(orderCode);
    }

}

JEP 361:Switch表達式:它允許將switch用作語句或表達式,簡化了日常的編碼,這是JDK 12和JDK 13中的預覽功能

String str = "A";
// Jdk之前的版本
switch (str) {
    case "A":
        System.out.println("A");break;
    case "B":
        System.out.println("B");break;
    default:
        System.out.println("default");
}

// Jdk12之後
switch (str) {
    case "A", "C" -> System.out.println("A || C");
    case "B" -> System.out.println("B");
    default -> System.out.println("default");
}

// yield用於返回值
int score = switch (str) {
    case "A" -> 90;
    case "B" -> 80;
    default -> {
        System.out.println("default");
        yield 70;
    }
};
System.out.println(score);

JEP 362:棄用Solaris和SPARC端口:在將來的發行版中將其刪除
放棄對這些端口的支持將使OpenJDK社區中的貢獻者能夠加速新功能的開發,這些新功能將推動平臺向前發展

JEP 363:刪除併發標記掃描(CMS)垃圾回收器
CMS垃圾收集器在兩年前已過時,並且自JDK 6起已成爲CMS的後繼產品的G1已成爲默認GC,並且已經在許多情況下大規模使用。我們還看到引入了兩個新的收集器,ZGC(Jdk11)和Shenandoah(Open Jdk12),同時對G1進行了許多改進 。CMS存在幾個弊端,比如會產生內存碎片,併發清理後導致用戶線程可用的空間不足,因爲是併發清理,所以對CPU資源非常敏感,而且無法處理浮動垃圾
詳細信息:https://openjdk.java.net/jeps/363

/**
 * 在Jdk14中通過-XX:+UseConcMarkSweepGC選項嘗試使用CMS的話會得到下面的警告信息
 * Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0
 */
List<String> list = new ArrayList<>();
while (true) {
    list.add("a");
}

JEP 364,JEP 365:ZGC on macOS and Windows:儘管大多數需要ZGC的用戶也需要基於Linux的環境的可伸縮性,但是在Windows和macOS中也經常需要部署和測試它。還有某些桌面應用程序將從ZGC功能中受益。因此,ZGC功能已移植到Windows和macOS
ZGC與Shenandoah目標非常相似,在儘可能對吞吐量影響不大的前提下,實現在任意堆內存大小下都可以把停頓時間限制在10毫秒以內。ZGC收集器是一款基於Region內存佈局的,(暫時)不設分代,使用了讀屏障、染色指針和內存多重映射等技術來實現可併發標記-壓縮算法,首要目標是低延遲
詳細信息:https://openjdk.java.net/jeps/364
在這裏插入圖片描述
在這裏插入圖片描述
上圖引用自:The Z Garbage Collector - An Introduction

/**
 * -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
 */
List<String> list = new ArrayList<>();
while (true) {
    list.add("a");
}

JEP 366:棄用ParallelScavenge + SerialOld GC組合,該組合很少使用,但需要大量維護工作
詳細信息:https://openjdk.java.net/jeps/366

/**
 * 使用-XX:+UseParallelGC -XX:-UseParallelOldGC或者-XX:-UseParallelOldGC參數啓用組合後提示以下信息
 * Java HotSpot(TM) 64-Bit Server VM warning: Option UseParallelOldGC was deprecated in version 14.0 and will likely be removed in a future release.
 */
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    while (true) {
        list.add("a");
    }
}

JEP 367:刪除Pack200工具和API:將刪除java.util.jar軟件包中的pack200和unpack200工具以及Pack200 API。這些工具和API 已在Java SE 11中棄用
刪除原因:https://openjdk.java.net/jeps/367

JEP 368:文本塊:在Java 首次將文本塊作爲預覽功能(JEP 355)引入時,收到反饋後,添加了兩個新的轉義序列。該功能增強了Java程序中用非Java語言編寫代碼的字符串的可讀性

// Jdk之前的版本
String sql1 = "select\n" +
        "\t*\n" +
        "from\n" +
        "\tord_order_item ooi\n" +
        "left join ord_order oo on\n" +
        "\tooi.order_id = oo.id\n" +
        "where\n" +
        "\too.order_code = 'TEST1001'\n" +
        "order by\n" +
        "\too.id desc";

// 三引號表示文本塊
String sql2 = """
        select
        	*
        from
        	ord_order_item ooi
        left join ord_order oo on
        	ooi.order_id = oo.id
        where
        	oo.order_code = 'TEST1001'
        order by
        	oo.id desc
        """;

// 新增“\s”表示空格,“\”表示去除換行
String sql3 = """
        select
        	*
        from
        	ord_order_item ooi
        left join ord_order oo on
        	ooi.order_id = oo.id
        where
        	oo.order_code = 'TEST1001'
        order by\s\
        oo.id desc
        """;
System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);

JEP 370:外部存儲器訪問API:此孵化器模塊引入了一個API,以允許Java程序安全有效地訪問Java堆之外的外部存儲器
詳細信息:https://openjdk.java.net/jeps/370

補充

在這裏插入圖片描述

鏈接

Java:https://www.oracle.com/java/
Jdk14:https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
The Arrival of Java 14:https://blogs.oracle.com/java-platform-group/the-arrival-of-java-14

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章