Java SE 17 新增特性

Java SE 17 新增特性

作者:Grey

原文地址:Java SE 17 新增特性

源碼

源倉庫: Github:java_new_features

鏡像倉庫: GitCode:java_new_features

Sealed Classes 正式啟用

Sealed Classes 在 Java SE 15 和 Java SE 16 中都是預覽功能, 在 Java SE 17 中成為正式功能。

示例代碼:

package git.snippets.jdk17;

/**
 * 密封類(Sealed Classes)
 *
 * @author <a href="mailto:[email protected]">Grey</a>
 * @date 2021/11/29
 * @since 17
 */
public class SealedClassInJdk17 {
    public static void main(String[] args) {

    }
}

sealed interface Dog permits Collie, TuGou {
    //...
}

sealed class Collie implements Dog permits BorderCollie {

}

final class BorderCollie extends Collie {
}

// 使用 non-sealed 關鍵字,表示可以被任意繼承
non-sealed class TuGou implements Dog {
}

增強型偽隨機數生成器

JEP 356為偽隨機數生成器(PRNG)提供了新的接口和實現。

因此,更容易互換使用不同的算法,而且它還為基於流的編程提供了更好的支持,示例代碼如下

package git.snippets.jdk17;

import java.util.random.RandomGeneratorFactory;
import java.util.stream.IntStream;

/**
 * @author <a href="mailto:[email protected]">Grey</a>
 * @date 2022/8/21
 * @since 17
 */
public class RandomNewDemo {
    public IntStream getPseudoInts(String algorithm, int streamSize) {
        // returns an IntStream with size @streamSize of random numbers generated using the @algorithm
        // where the lower bound is 0 and the upper is 100 (exclusive)
        return RandomGeneratorFactory.of(algorithm)
                .create()
                .ints(streamSize, 0, 100);
    }
}

傳統的隨機類,如java.util.Random、SplittableRandomSecureRandom現在擴展了新的RandomGenerator接口。

恢復始終嚴格的浮點語義

這個 JEP 主要用於科學應用,它使浮點運算始終保持嚴格。默認的浮點運算是 strict 或 strictfp ,兩者都能保證在每個平台上的浮點計算結果相同。

在 Java 1.2 之前,strictfp 行為也是默認的。然而,由於硬件問題,必須使用關鍵字 strictfp 來重新啟用這種行為, 但是現在已經不需要使用這個關鍵字了。

詳見: JEP 306

廢棄 Applet API

由於許多網絡瀏覽器已經取消了對 Java 插件的支持。所以 Java SE 17 將 Applet API 標記為刪除。

強化封裝 JDK 的內部結構

從 Java 9 引入模塊化開始,JDK 對於其內部的 API 的訪問限制就已經明確開始落地,只是當時我們可以通過配置啟動參數 –illegal-access 來繼續使用 JDK 的內部 API,其中 Java 9 ~ Java 15 這個參數默認 permit,Java 16 默認 deny。

JEP 403中刪除了標誌-illegal-access,平台將忽略該標誌,如果該標誌存在,控制台將發出消息告知該標誌的終止。按照提案的說明,被嚴格限制的這些內部 API 包括:

java.*包下面的部分非public類、方法、屬性,例如Classloader當中的defineClass等等。

sun.*下的所有類及其成員都是內部 API。

絕大多數com.sun.*jdk.*org.*包下面的類及其成員也是內部 API。

具體可參考:Java 17 更新(6):制裁!我自己私有的 API 你們怎麼隨便一個人都想用?

Switch類型匹配(預覽功能)

這是通過加強 switch 表達式和語句的模式匹配能力,減少了定義這些表達式所需的模板,此外,switch 中增加了空值的支持。

示例代碼

package git.snippets.jdk17;


/**
 * switch類型匹配(預覽功能)
 *
 * @author <a href="mailto:[email protected]">Grey</a>
 * @date 2021/11/29
 * @since 17
 */
public class SwitchMatchTest {
    public static void main(String[] args) {

    }

    record Human(String name, int age, String profession) {
    }

    record Circle() implements Shape {
        public int getNumberOfSides() {
            return 0;
        }
    }

    interface Shape {
    }

    record Triangle() implements Shape {
        public int getNumberOfSides() {
            return 0;
        }
    }

    public String checkObject(Object obj) {
        return switch (obj) {
            case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession());
            case Circle c -> "This is a circle";
            case Shape s -> "It is just a shape";
            case null -> "It is null";
            default -> "It is an object";
        };
    }

    public String checkShape(Shape shape) {
        return switch (shape) {
            case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle";
            case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle";
            default -> "Just a normal shape";
        };
    }
}

移除 RMI Activation

詳見:JEP 407: Remove RMI Activation

刪除實驗性 AOT 和 JIT 編譯器

在 Java SE 9中,JEP 295 引入了超前編譯(jaotc 工具),作為一個實驗性功能。後來的 Java SE 10,JEP 317 又提出它是一個實驗性的 JIT 編譯器。

然而,這個功能自從它們被引入後就沒有什麼用處了,而且需要大量的精力來維護它,所以這個 JEP 刪除了基於 Java 的實驗性超前(AOT)和及時(JIT)編譯器

以下 AOT 包、類、工具和代碼被刪除。

jdk.aot — the jaotc tool

jdk.internal.vm.compiler — the Graal compiler

jdk.internal.vm.compiler.management — Graal』s MBean

src/hotspot/share/aot — dumps and loads AOT code

以及由#if INCLUDE_AOT保護的額外代碼

詳見:JEP 410: Remove the Experimental AOT and JIT Compiler

Foreign Function & Memory API(孵化功能)

這個外來函數和內存API允許開發者訪問 JVM 之外的代碼(Foreign Function)、存儲在 JVM 之外的數據(堆外數據),以及訪問不由 JVM 管理的內存(foreign memory)。

P.S 這是一個孵化功能;需要添加--add-modules jdk.incubator.foreign來編譯和運行 Java 代碼。

一個示例:

Foreign Linker API examples in Java 16

詳見:JEP 412: Foreign Function & Memory API (Incubator)

更多

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

參考資料

JDK 17 Release Notes

Java17新特性

New Features in Java 17

What is new in Java 17