专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java25的新特性_java最新特性

temp10 2025-09-19 02:36:54 java教程 1 ℃ 0 评论

Java语言特性系列

  • Java5的新特性
  • Java6的新特性
  • Java7的新特性
  • Java8的新特性
  • Java9的新特性
  • Java10的新特性
  • Java11的新特性
  • Java12的新特性
  • Java13的新特性
  • Java14的新特性
  • Java15的新特性
  • Java16的新特性
  • Java17的新特性
  • Java18的新特性
  • Java19的新特性
  • Java20的新特性
  • Java21的新特性
  • Java22的新特性
  • Java23的新特性
  • Java24的新特性
  • Java25的新特性
  • Java26的新特性

本文主要讲述一下Java25的新特性

Java25的新特性_java最新特性

版本号

openjdk version "25" 2025-09-16
OpenJDK Runtime Environment (build 25+36-3489)
OpenJDK 64-Bit Server VM (build 25+36-3489, mixed mode, sharing)

从version信息可以看出是build 25+36

特性列表

JEP 470: PEM Encodings of Cryptographic Objects (Preview)

本特性为Java平台引入了一套简洁、易用且线程安全的API(Preview版本),用于在 PEM(Privacy-Enhanced Mail)文本与各类密码学对象(密钥、证书、CRL 等)之间进行双向转换,解决开发者长期需要手写解析/格式化逻辑的痛点。

  • DEREncodable 标记接口
    统一标识可参与 PEM 编解码的已有类型:
    AsymmetricKey、X509Certificate、X509CRL、KeyPair、EncryptedPrivateKeyInfo、PKCS8EncodedKeySpec、X509EncodedKeySpec 以及新引入的 PEMRecord。
  • PEMEncoder / PEMDecoder
    不可变、可复用、线程安全。
    支持直接编解码字符串或字节流,提供 encode(DerEncodable) / decode(String/InputStream) 等便捷方法。
    通过 withEncryption(char[] password) / withDecryption(…) 一键加解密私钥;默认算法可在安全属性文件中配置(当前为 PBEWithHmacSHA256AndAES_128)。
    通过 withFactory(Provider) 可指定特定加密提供者。
  • PEMRecord 记录类
    用于处理平台暂无对应 API 的 PEM 类型(如 PKCS#10 请求)或需要保留 PEM 首部前导数据的场景。
  • EncryptedPrivateKeyInfo 增强
    新增静态工厂方法 encryptKey(…) 与实例方法 getKey(…),方便先加密成 EncryptedPrivateKeyInfo 再编码为 PEM,或解码后直接解密拿到 PrivateKey。

使用示例

public class PEMEncoding {
    public static void main() throws NoSuchAlgorithmException {
        // Enable preview features: --enable-preview --release 25

        // 1. Generate an EC key pair
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // 2. Encode public key to PEM
        String publicKeyPEM = PEMEncoder.of()
                .encodeToString(keyPair.getPublic());
        System.out.println("Public Key PEM:\n" + publicKeyPEM);

        // 3. Encode a private key to encrypted PEM
        char[] password = "secret".toCharArray();
        String privateKeyPEM = PEMEncoder.of()
                .withEncryption(password)
                .encodeToString(keyPair.getPrivate());
        System.out.println("Encrypted Private Key PEM:\n" + privateKeyPEM);

        // 4. Decode a public key
        PublicKey decodedPubKey = PEMDecoder.of()
                .decode(publicKeyPEM, PublicKey.class);
        System.out.println("Decoded Public Key Algo: " + decodedPubKey.getAlgorithm());

        // 5. Decode encrypted private key
        PrivateKey decodedPrivateKey = PEMDecoder.of()
                .withDecryption(password)
                .decode(privateKeyPEM, PrivateKey.class);
        System.out.println("Decoded Private Key Algo: " + decodedPrivateKey.getAlgorithm());
    }
}

编译及运行

javac --release 25 --enable-preview PEMEncoding.java
java  --enable-preview PEMEncoding

JEP 502: Stable Values (Preview)

本特性引入了一种名为 Stable Values(稳定值) 的 API,用于支持延迟初始化的不可变数据持有者对象。这一特性在 JDK 25 中以预览功能形式提供,旨在提升 Java 应用的启动性能与并发安全性,同时保留 final 字段的优化能力(如常量折叠)。 Stable Values填补了final字段与可变字段之间的空白,在保持不可变性和线程安全的同时,支持按需初始化,特别适用于启动时需要延迟加载资源的大型应用场景。

使用示例如下:

class OrderController {

    // OLD:
    // private Logger logger = null;

    // NEW:
    private final StableValue<Logger> logger = StableValue.of();

    Logger getLogger() {
        return logger.orElseSet(() -> Logger.create(OrderController.class));
    }

    void submitOrder(User user, List<Product> products) {
        getLogger().info("order started");
        ...
        getLogger().info("order submitted");
    }

}

由于是预览版本,所以需要--enable-preview启用

javac --release 25 --enable-preview Main.java
java --enable-preview Main

JEP 503: Remove the 32-bit x86 Port

在JDK21的JEP 449: Deprecate the Windows 32-bit x86 Port for Removal已经废弃了对Windows 32位 x86的移植
在JDK24的JEP 479: Remove the Windows 32-bit x86 Port删除了相关源代码、移除了对windows 32位相关构建支持
在JDK24的JEP 501: Deprecate the 32-bit x86 Port for Removal废弃了对32位x86的移植,但是可以通过
--enable-deprecated-ports=yes来启用构建
在JDK25Z则删除了相关源代码、移除了相关构建支持

JEP 505: Structured Concurrency (Fifth Preview)

JDK19的JEP 428: Structured Concurrency (Incubator)作为第一次incubator
JDK20的JEP 437: Structured Concurrency (Second Incubator)作为第二次incubator
JDK21的JEP 453: Structured Concurrency (Preview)作为首次preview
JDK22的JEP 462: Structured Concurrency (Second Preview)作为第二次preview
JDK23的JEP 480: Structured Concurrency (Third Preview)作为第三次preview
JDK24的JEP 499: Structured Concurrency (Fourth Preview)作为第四次preview
JDK25作为第五次preview

使用示例如下:

Response handle() throws InterruptedException {

    try (var scope = StructuredTaskScope.open()) {

        Subtask<String> user = scope.fork(() -> findUser());
        Subtask<Integer> order = scope.fork(() -> fetchOrder());

        scope.join();   // Join subtasks, propagating exceptions

        // Both subtasks have succeeded, so compose their results
        return new Response(user.get(), order.get());

    }

}

JEP 506: Scoped Values

JDK19的JEP 428: Structured Concurrency (Incubator)作为第一次incubator
JDK20的JEP 437: Structured Concurrency (Second Incubator)作为第二次incubator
JDK21的JEP 453: Structured Concurrency (Preview)作为首次preview
JDK22的JEP 462: Structured Concurrency (Second Preview)作为第二次preview
JDK23的JEP 480: Structured Concurrency (Third Preview)作为第三次preview
JDK24的JEP 487: Scoped Values (Fourth Preview)作为第四次preview,与JDK23不同的是callWhere以及runWhere方法从ScopedValue类中移除,可以使用ScopedValue.where()再链式调用run(Runnable)或者call(Callable)

JDK25作为第五次preview,有个改动就是ScopedValue.orElse方法不再接受null作为参数

示例:

class Framework {

    private static final ScopedValue<FrameworkContext> CONTEXT
                        = ScopedValue.newInstance();    // (1)

    void serve(Request request, Response response) {
        var context = createContext(request);
        where(CONTEXT, context)                         // (2)
                   .run(() -> Application.handle(request, response));
    }
    
    public PersistedObject readKey(String key) {
        var context = CONTEXT.get();                    // (3)
        var db = getDBConnection(context);
        db.readKey(key);
    }

}

在 (1) 中,框架声明了一个作用域值,而不是一个thread local变量。在 (2),serve方法调用where … run而不是thread local的set方法。run方法提供了数据的单向共享serve方法到readKey方法。(3) 读取的值是由Framework.serve的时候写入的。

JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)

JDK19的JEP 405: Record Patterns (Preview)将Record的模式匹配作为第一次preview
JDK20的JEP 432: Record Patterns (Second Preview)作为Record模式匹配第二次preview
JDK21的JEP 440: Record Patterns则将Record模式匹配正式发布
JDK23的JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview)将原始类型的匹配作为第一次preview
JDK24的JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview)作为第二次preview
JDK25作为第三次preview

record Point(int x, int y) {}

// As of Java 21
static void printSum(Object obj) {
    if (obj instanceof Point(int x, int y)) {
        System.out.println(x+y);
    }
}

enum Color { RED, GREEN, BLUE }
record ColoredPoint(Point p, Color c) {}
record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {}
// As of Java 21
static void printUpperLeftColoredPoint(Rectangle r) {
    if (r instanceof Rectangle(ColoredPoint ul, ColoredPoint lr)) {
         System.out.println(ul.c());
    }
}

static void printColorOfUpperLeftPoint(Rectangle r) {
    if (r instanceof Rectangle(ColoredPoint(Point p, Color c),
                               ColoredPoint lr)) {
        System.out.println(c);
    }
}

但是这个只是支持Record类型

在JDK14JEP 305: Pattern Matching for instanceof (Preview)作为preview
在JDK15JEP 375: Pattern Matching for instanceof (Second Preview)作为第二轮的preview
在JDK16JEP 394: Pattern Matching for instanceof转正
JDK17引入JEP 406: Pattern Matching for switch (Preview)
JDK18的JEP 420: Pattern Matching for switch (Second Preview)则作为第二轮preview
JDK19的JEP 427: Pattern Matching for switch (Third Preview)作为第三轮preview
JDK20的JEP 433: Pattern Matching for switch (Fourth Preview)作为第四轮preview
JDK21的JEP 441: Pattern Matching for switch将Pattern Matching for switch作为正式版本发布,示例如下

// Prior to Java 21
static String formatter(Object obj) {
    String formatted = "unknown";
    if (obj instanceof Integer i) {
        formatted = String.format("int %d", i);
    } else if (obj instanceof Long l) {
        formatted = String.format("long %d", l);
    } else if (obj instanceof Double d) {
        formatted = String.format("double %f", d);
    } else if (obj instanceof String s) {
        formatted = String.format("String %s", s);
    }
    return formatted;
}

// As of Java 21
static String formatterPatternSwitch(Object obj) {
    return switch (obj) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        default        -> obj.toString();
    };
}

// As of Java 21
static void testFooBarNew(String s) {
    switch (s) {
        case null         -> System.out.println("Oops");
        case "Foo", "Bar" -> System.out.println("Great");
        default           -> System.out.println("Ok");
    }
}

// As of Java 21
static void testStringEnhanced(String response) {
    switch (response) {
        case null -> { }
        case "y", "Y" -> {
            System.out.println("You got it");
        }
        case "n", "N" -> {
            System.out.println("Shame");
        }
        case String s
        when s.equalsIgnoreCase("YES") -> {
            System.out.println("You got it");
        }
        case String s
        when s.equalsIgnoreCase("NO") -> {
            System.out.println("Shame");
        }
        case String s -> {
            System.out.println("Sorry?");
        }
    }
}

// As of Java 21
static void exhaustiveSwitchWithBetterEnumSupport(CardClassification c) {
    switch (c) {
        case Suit.CLUBS -> {
            System.out.println("It's clubs");
        }
        case Suit.DIAMONDS -> {
            System.out.println("It's diamonds");
        }
        case Suit.HEARTS -> {
            System.out.println("It's hearts");
        }
        case Suit.SPADES -> {
            System.out.println("It's spades");
        }
        case Tarot t -> {
            System.out.println("It's a tarot");
        }
    }
}

// As of Java 21
sealed interface Currency permits Coin {}
enum Coin implements Currency { HEADS, TAILS } 

static void goodEnumSwitch1(Currency c) {
    switch (c) {
        case Coin.HEADS -> {    // Qualified name of enum constant as a label
            System.out.println("Heads");
        }
        case Coin.TAILS -> {
            System.out.println("Tails");
        }
    }
}

static void goodEnumSwitch2(Coin c) {
    switch (c) {
        case HEADS -> {
            System.out.println("Heads");
        }
        case Coin.TAILS -> {    // Unnecessary qualification but allowed
            System.out.println("Tails");
        }
    }
}

// As of Java 21
static void testNew(Object obj) {
    switch (obj) {
        case String s when s.length() == 1 -> ...
        case String s                      -> ...
        ...
    }
}

但是JDK21还不支持原始类型的匹配

而支持原始类型的匹配使用示例如下:

switch (x.getStatus()) {
    case 0 -> "okay";
    case 1 -> "warning";
    case 2 -> "error";
    default -> "unknown status: " + x.getStatus();
}

switch (x.getStatus()) {
    case 0 -> "okay";
    case 1 -> "warning";
    case 2 -> "error";
    case int i -> "unknown status: " + i;
}

switch (x.getYearlyFlights()) {
    case 0 -> ...;
    case 1 -> ...;
    case 2 -> issueDiscount();
    case int i when i >= 100 -> issueGoldCard();
    case int i -> ... appropriate action when i > 2 && i < 100 ...
}

long v = ...;
switch (v) {
    case 1L              -> ...;
    case 2L              -> ...;
    case 10_000_000_000L -> ...;
    case 20_000_000_000L -> ...;
    case long x          -> ... x ...;
}

if (roomSize instanceof byte) { // check if value of roomSize fits in a byte
    ... (byte) roomSize ... // yes, it fits! but cast is required
}

另外针对instanceof示例如下:

byte b = 42;
b instanceof int;         // true (unconditionally exact)

int i = 42;
i instanceof byte;        // true (exact)

int i = 1000;
i instanceof byte;        // false (not exact)

int i = 16_777_217;       // 2^24 + 1
i instanceof float;       // false (not exact)
i instanceof double;      // true (unconditionally exact)
i instanceof Integer;     // true (unconditionally exact)
i instanceof Number;      // true (unconditionally exact)

float f = 1000.0f;
f instanceof byte;        // false
f instanceof int;         // true (exact)
f instanceof double;      // true (unconditionally exact)

double d = 1000.0d;
d instanceof byte;        // false
d instanceof int;         // true (exact)
d instanceof float;       // true (exact)

Integer ii = 1000;
ii instanceof int;        // true (exact)
ii instanceof float;      // true (exact)
ii instanceof double;     // true (exact)

Integer ii = 16_777_217;
ii instanceof float;      // false (not exact)
ii instanceof double;     // true (exact)

JEP 508: Vector API (Tenth Incubator)

JDK16引入了JEP 338: Vector API (Incubator)提供了jdk.incubator.vector来用于矢量计算
JDK17进行改进并作为第二轮的incubatorJEP 414: Vector API (Second Incubator)
JDK18的JEP 417: Vector API (Third Incubator)进行改进并作为第三轮的incubator
JDK19的JEP 426:Vector API (Fourth Incubator)作为第四轮的incubator
JDK20的JEP 438: Vector API (Fifth Incubator)作为第五轮的incubator
JDK21的JEP 448: Vector API (Sixth Incubator)作为第六轮的incubator
JDK22的JEP 460: Vector API (Seventh Incubator)作为第七轮的incubator
JDK23的JEP 469: Vector API (Eighth Incubator)作为第八轮incubator
JDK24的JEP 489: Vector API (Ninth Incubator)则作为第九轮incubator,与JDK23相比做了一些变动:比如引入了一个新的基于值的类Float16,用于表示IEEE 754二进制16格式的16位浮点数。

JDK25作为第十轮incubator,主要变化是:VectorShuffle现在支持访问和访问MemorySegment,该实现是通过Foreign Function & Memory API (JEP 454) 而不是通过HotSpot内部的C++代码,提高了可维护性,另外对Float16值的加法、减法、除法、乘法、平方根和fused乘法/加法运算现在支持x64 cpu自动矢量化

JEP 509: JFR CPU-Time Profiling (Experimental)

本特性引入了实验版的CPU-Time Profiling,可以捕获更准确的CPU时间分析信息
使用示例

$ java -XX:StartFlightRecording=jdk.CPUTimeSample#enabled=true,filename=profile.jfr ...
$ jfr view cpu-time-hot-methods profile.jfr

配合jcmd使用如下

jcmd <pid> JFR.start settings=/tmp/cpu_profile.jfc duration=4m
jcmd <pid> JFR.stop

JEP 510: Key Derivation Function API

JDK 21中包含的KEM API(JEP 452)是HPKE的一个组成部分,标志着Java朝着HPKE迈出的第一步,并为后量子挑战做好了准备。
在JDK24的JEP 478: Key Derivation Function API (Preview)中提出了HPKE的另一个组成部分,作为这一方向上的下一步:密钥派生函数(KDFs)的API,作为预览版本
在JDK25转为正式版,无需
--enable-preview参数

使用示例如下:

// Create a KDF object for the specified algorithm
KDF hkdf = KDF.getInstance("HKDF-SHA256"); 

// Create an ExtractExpand parameter specification
AlgorithmParameterSpec params =
    HKDFParameterSpec.ofExtract()
                     .addIKM(initialKeyMaterial)
                     .addSalt(salt).thenExpand(info, 32);

// Derive a 32-byte AES key
SecretKey key = hkdf.deriveKey("AES", params);

// Additional deriveKey calls can be made with the same KDF object

JEP 511: Module Import Declarations

与JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview)类似,本特性主要是为了简化语法方便新手使用,通过新引入module的import,来一次性导入module下所有package底下的类

JDK23的JEP 476: Module Import Declarations (Preview)作为第一个preview
JDK24的JEP 494: Module Import Declarations (Second Preview)作为第二次preview,与JDK23不同的是取消了模块不允许声明对java.base模块传递依赖的限制,并修订了java.se模块声明,使其传递性地依赖于java.base模块。这些变化意味着导入java.se模块将按需导入整个Java SE API。此外,现在允许按需声明的类型导入声明覆盖模块导入声明。
JDK25作为正式版,没有变化

示例:

import module java.base;  // 包含了import java.io.*; import java.util.*;

import module java.base;      // exports java.util, which has a public Date class
import module java.sql;       // exports java.sql, which has a public Date class

import java.sql.Date;         // resolve the ambiguity of the simple name Date!

...
Date d = ...                  // Ok!  Date is resolved to java.sql.Date
...

由于是正式版,不再需要使用--enable-preview参数来开启

JEP 512: Compact Source Files and Instance Main Methods

JDK21的JEP 445: Unnamed Classes and Instance Main Methods (Preview)作为首次preview,引入了未命名的类和实例main方法特性可以简化hello world示例,方便java新手入门
JDK22的JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview)作为第二次的preview
JDK23的JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview)作为第三次preview
JDK24的JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview)则作为第四次preview
JDK25作为正式版本,有些改动:

  • console I/O的新IO类现在位于java.lang,而不是java.io包,现在隐式导入到每个源文件
  • IO类的静态方法不再隐式导入compact source files,需要显示导入
  • IO类的实现基于System.out及System.in,而非java.io.Console类

示例如下:

void main() {
    String name = IO.readln("Please enter your name: ");
    IO.print("Pleased to meet you, ");
    IO.println(name);
}

JEP 513: Flexible Constructor Bodies

JDK22的JEP 447: Statements before super(…) (Preview)作为第一次preview
JDK23的JEP 482: Flexible Constructor Bodies (Second Preview)作为第二次preview
JDK24的JEP 492: Flexible Constructor Bodies (Third Preview)作为第三次preview
JDK25作为正式版本,没有变化

比如在JEP 447之前的代码如下:

public class PositiveBigInteger extends BigInteger {

    public PositiveBigInteger(long value) {
        super(value);               // Potentially unnecessary work
        if (value <= 0)
            throw new IllegalArgumentException(non-positive value);
    }

}

在JEP 447之后代码可以如下:

public class PositiveBigInteger extends BigInteger {

    public PositiveBigInteger(long value) {
        if (value <= 0)
            throw new IllegalArgumentException(non-positive value);
        super(value);
    }

}

JEP 514: Ahead-of-Time Command-Line Ergonomics

在JDK24的JEP 483: Ahead-of-Time Class Loading & Linking支持了通过Ahead-of-Time Cache来存储已经读取、解析、加载和链接的类
在JDK25则通过简化常见用例所需的命令来加速java应用程序的启动。

在JDK24时分两步创建AOT缓存:

  • 首先运行application来记录AOT配置:
java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -cp app.jar com.example.App ...
  • 接着使用该配置来创建AOT缓存:
java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -cp app.jar
  • 最后使用AOT缓存启动:
java -XX:AOTCache=app.aot -cp app.jar com.example.App ...

AOT缓存将读取、解析、加载和链接(通常在程序执行期间即时完成)的任务提前到缓存创建的早期阶段。因此,在执行阶段,程序启动速度更快,因为其类可以从缓存中快速访问。其性能提升可以高达 42%。
但是需要运行2次来创建AOT缓存。留下AOT配置文件也很不方便,它只是一个临时文件,生产运行不需要,可以删除。

JDK25通过引入AOTCacheOutput将两步合为一步,它实际上将其调用拆分为两个子调用: 第一个执行训练运行 (AOTMode=record),然后第二个创建AOT缓存 (AOTMode=create),可以通过新的环境变量JDK_AOT_VM_OPTIONS来覆盖传递给cache create这个子过程的VM命令。

java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App ...

当以这种方式操作时,JVM为AOT配置创建临时文件,并在完成时删除该文件。

使用的时候一样:

java -XX:AOTCache=app.aot -cp app.jar com.example.App ...

JEP 515: Ahead-of-Time Method Profiling

在JDK24的JEP 483: Ahead-of-Time Class Loading & Linking支持了通过Ahead-of-Time Cache来存储已经读取、解析、加载和链接的类
JVM可以识别执行最频繁或消耗最多CPU时间的代码,并通过将其编译为本机代码来优化此代码。此过程称为分析。简单来说,配置文件是与方法相关的有用信息的集合,例如已执行的次数。当应用程序以通常的方式 (没有AOT缓存) 运行时,这些配置文件在应用程序执行开始时收集。这个JEP背后的概念是,我们可以在训练运行期间收集配置文件,然后在后续运行中重复使用它们。这意味着在以后的执行中,无需在启动后收集配置文件,从而可以立即开始代码编译。训练运行的质量会显着影响应用程序预热时间的改善。训练跑得越好,在随后的跑中获得的性能增强就越大。
本特性将生产环境做的Method Profiling挪到了Ahead-of-Time Cache阶段,使得生产环境启动的时候就读取这些数据,JIT立即对真正的热点方法进行编译,无需边跑边收集。

JEP 518: JFR Cooperative Sampling

本特性提高JFR异步采样Java线程堆栈时的稳定性,通过仅在安全点处遍历调用堆栈来实现此目的,同时最大程度地减少安全点偏差。

JEP 519: Compact Object Headers

在JDK24的JEP 450: Compact Object Headers (Experimental)特性中,在64位架构上,将 HotSpot JVM中的对象标头大小从96到128位减少到64位。在SPECjbb2015的测试中减少了22%的堆空间和8%的CPU时间,完成的垃圾收集数量为减少15%,一个高度并行的JSON解析器基准运行时间减少10%。
在JDK25转为正式版,无需
-XX:+
UnlockExperimentalVMOptions
命令

-XX:+UseCompactObjectHeaders

JEP 520: JFR Method Timing & Tracing

本特性引入了两个新的JFR事件,jdk.MethodTiming和jdk.MethodTrace,通过字节码织入来追踪方法
使用示例

$ java -XX:StartFlightRecording:jdk.MethodTrace#filter=java.util.HashMap::resize,filename=recording.jfr ...
$ jfr print --events jdk.MethodTrace --stack-depth 20 recording.jfr
jdk.MethodTrace {
    startTime = 00:39:26.379 (2025-03-05)
    duration = 0.00113 ms
    method = java.util.HashMap.resize()
    eventThread = "main" (javaThreadId = 3)
    stackTrace = [
      java.util.HashMap.putVal(int, Object, Object, boolean, boolean) line: 636
      java.util.HashMap.put(Object, Object) line: 619
      sun.awt.AppContext.put(Object, Object) line: 598
      sun.awt.AppContext.<init>(ThreadGroup) line: 240
      sun.awt.SunToolkit.createNewAppContext(ThreadGroup) line: 282
      sun.awt.AppContext.initMainAppContext() line: 260
      sun.awt.AppContext.getAppContext() line: 295
      sun.awt.SunToolkit.getSystemEventQueueImplPP() line: 1024
      sun.awt.SunToolkit.getSystemEventQueueImpl() line: 1019
      java.awt.Toolkit.getEventQueue() line: 1375
      java.awt.EventQueue.invokeLater(Runnable) line: 1257
      javax.swing.SwingUtilities.invokeLater(Runnable) line: 1415
      java2d.J2Ddemo.main(String[]) line: 674
    ]
}

JEP 521: Generational Shenandoah

在JDK24的JEP 404: Generational Shenandoah (Experimental)提供了一个实验性的分代模式,与其他分代收集器一样分为年轻代和年老代
在JDK25转为正式版本,不再需要
-XX:+
UnlockExperimentalVMOptions
命令

-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational

细项解读

上面列出的是大方面的特性,除此之外还有一些api的更新及废弃,主要见JDK 25 Release Notes,这里举几个例子。

添加项

  • Support for reading all remaining characters from a Reader (JDK-8354724)

java.io.Reader新增了方法readAllAsString可以读取剩余字符到String,新增readAllLines读取剩余字符到List<String>

  • New connectionLabel Method in java.net.http.HttpResponse to Identify Connections (JDK-8350279)

对HttpResponse新增了connectionLabel方法用于关联connection

  • New Property to Construct ZIP FileSystem as Read-only (JDK-8350880)

新增readOnly支持FileSystems.newFileSystem(pathToZipFile, Map.of(“accessMode”,“readOnly”))

  • Updates to ForkJoinPool and CompletableFuture (JDK-8319447)

ForkJoinPool做了更新以实现ScheduledExecutorService,新增了submitWithTimeout方法支持timeout参数

  • Thread Dumps Generated by HotSpotDiagnosticMXBean.dumpThreads and jcmd Thread.dump_to_file Updated to Include Lock Information (JDK-8356870)


com.sun.management.HotSpotDiagnosticMXBean.dumpThreads以及jcmd Thread.dump_to_file生成的线程堆栈现在包含了锁信息

  • G1 Reduces Remembered Set Overhead by Grouping Regions into Shared Card Sets (JDK-8343782)

以前每个Region都维护自己的G1CardSet,导致内存占用高,新设计在 Remark 阶段之后,把预计会一起被清空的Region归为一组,并分配同一个共享的G1CardSet,省去了它们之间逐一跟踪引用的开销。

移除项

  • java.net.Socket Constructors Can No Longer Be Used to Create a Datagram Socket (JDK-8356154)

java.net.Socket废弃了两个构造器,不再支持创建datagram sockets,需要改为java.net.DatagramSocket替代

  • Removal of PerfData Sampling (JDK-8241678)


-XX:PerfDataSamplingInterval这个被移除了

废弃项

  • Deprecate the Use of java.locale.useOldISOCodes System Property (JDK-8353118)


java.locale.useOldISOCodes这个属性被废弃了

  • The UseCompressedClassPointers Option is Deprecated (JDK-8350753)


UseCompressedClassPointers这个参数被废弃了,接下来将默认开启压缩类指针

  • Various Permission Classes Deprecated for Removal (JDK-8348967, JDK-8353641, JDK-8353642, JDK-8353856, JDK-8347985, JDK-8351224, JDK-8351310)
    以下这些Permission相关的类被标记废弃
java.security.UnresolvedPermission
javax.net.ssl.SSLPermission
javax.security.auth.AuthPermission
javax.security.auth.PrivateCredentialPermission
javax.security.auth.kerberos.DelegationPermission
javax.security.auth.kerberos.ServicePermission
com.sun.security.jgss.InquireSecContextPermission
java.lang.RuntimePermission
java.lang.reflect.ReflectPermission
java.io.FilePermission
java.io.SerializablePermission
java.nio.file.LinkPermission
java.util.logging.LoggingPermission
java.util.PropertyPermission
jdk.jfr.FlightRecorderPermission
java.net.NetPermission
java.net.URLPermission
jdk.net.NetworkPermission
com.sun.tools.attach.AttachPermission
com.sun.jdi.JDIPermission
java.lang.management.ManagementPermission
javax.management.MBeanPermission
javax.management.MBeanTrustPermission
javax.management.MBeanServerPermission
javax.management.remote.SubjectDelegationPermission

已知问题修复

  • ZGC Now Avoids String Deduplication for Short-Lived Strings (JDK-8347337)

ZGC将避免对一些生命周期短的String进行Deduplication,避免不必要的开销

  • G1 Reduces Pause Time Spikes by Improving Region Selection (JDK-8351405)

G1在Mixed GC的时候会引起pause time飙升,此次通过region选择进行了优化

  • No More OutOfMemoryErrors Due to JNI in Serial/Parallel GC (JDK-8192647)

修复了Serial/Parallel GC因为JNI导致的OOM

已知问题

  • Regression in Serialization of LocalDate Class Objects (JDK-8367031)
    在 java.time 包中,若干类的序列化 Class 对象在 JDK 25 与早期版本之间不再兼容。受影响的具体类包括:LocalDate、YearMonth、MonthDay、HijrahDate
    兼容性规则:如果把上述某个类的Class对象在早期版本序列化,再到 JDK 25 反序列化,或者反向操作,都会抛出 InvalidClassException,例如
    writeObject(LocalDate.class)
    但如果是序列化实例,则不受影响writeObject(LocalDate.now())
  • Performance Regression in java.lang.ClassValue::get (JDK-8358535)
    在 JDK 25 中,为了增强 ClassValue 在各种并发场景下的健壮性,JDK-8351996 对其进行了更新。
    然而,这次改动导致:在调用 ClassValue.remove 之后,ClassValue.get 的执行速度明显变慢。
    • 大多数应用不会直接使用 ClassValue,因此不会感知到这一退化。
    • 但若某个库同时调用 ClassValue.get 与 remove(例如 Scala 2.12 的标准库),就可能受到性能影响。
      该性能回退已在 JDK-8358535 中被修复。
  • -XX:+UseTransparentHugePages Fails to Enable Huge Pages for G1 (JDK-8366434)
    在把Transparent Huge Pages(THP)模式设置为 madvise 的系统上,
    即使启动参数里加了 -XX:+UseTransparentHugePages,默认垃圾回收器 G1 也不会实际启用大页。临时解决办法:把 THP 模式改成 always,即可让 G1 正常使用Transparent Huge Pages:
# echo always > /sys/kernel/mm/transparent_hugepage/enabled

其他事项

  • Disabled SHA-1 in TLS 1.2 and DTLS 1.2 Handshake Signatures (JDK-8340321)
  • Compact Object Headers CDS Archive Generation and jlink Instruction (JDK-8350457)

小结

Java25主要有如下几个特性,其中核心库改动有JEP 502、JEP 505、JEP 506、JEP 508,语言规范类的有JEP507、JEP 511、JEP 512、JEP 513。

  • JEP 470: PEM Encodings of Cryptographic Objects (Preview)
  • JEP 502: Stable Values (Preview)
  • JEP 503: Remove the 32-bit x86 Port
  • JEP 505: Structured Concurrency (Fifth Preview)
  • JEP 506: Scoped Values
  • JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)
  • JEP 508: Vector API (Tenth Incubator)
  • JEP 509: JFR CPU-Time Profiling (Experimental)
  • JEP 510: Key Derivation Function API
  • JEP 511: Module Import Declarations
  • JEP 512: Compact Source Files and Instance Main Methods
  • JEP 513: Flexible Constructor Bodies
  • JEP 514: Ahead-of-Time Command-Line Ergonomics
  • JEP 515: Ahead-of-Time Method Profiling
  • JEP 518: JFR Cooperative Sampling
  • JEP 519: Compact Object Headers
  • JEP 520: JFR Method Timing & Tracing
  • JEP 521: Generational Shenandoah

此次发布了18个JEP,整体概括如下:

JEP

Title

Status

Project

Feature Type

Changes since Java 24

470

PEM Encodings of Cryptographic Objects

Preview

Security Libs

Security

New feature

502

Stable Values

Preview

Core Libs

New API

New feature

503

Remove the 32-bit x86 Port


HotSpot

Deprecation

Removal

505

Structured Concurrency

Fifth Preview

Loom

Concurrency

Major

506

Scoped Values


Loom

Concurrency

Minor

507

Primitive Types in Patterns, instanceof, and switch

Third Preview

Amber

Language

None

508

Vector API

Tenth Incubator

Panama

New API

Minor

509

JFR CPU-Time Profiling

Experimental

HotSpot / JFR

Profiling

New feature

510

Key Derivation Function API


Security Libs

Security

None

511

Module Import Declarations


Amber

Language

None

512

Compact Source Files and Instance Main Methods


Amber

Language

Major

513

Flexible Constructor Bodies


Amber

Language

None

514

Ahead-of-Time Command-Line Ergonomics


Leyden

Performance

New feature

515

Ahead-of-Time Method Profiling


Leyden

Performance

New feature

518

JFR Cooperative Sampling


HotSpot / JFR

Profiling

New feature

519

Compact Object Headers


HotSpot

Performance

None

520

JFR Method Timing & Tracing


HotSpot / JFR

Profiling

New feature

521

Generational Shenandoah


HotSpot / GC

Performance

Stability and performance improvements

doc

  • JDK 25 Features
  • JDK 25 Release Notes
  • Consolidated JDK 25 Release Notes
  • Java SE 25 deprecated-list
  • The Arrival of Java 25
  • Java 25, the Next LTS Release, Delivers Finalized Features and Focus on Performance and Runtime
  • JDK 25 and JDK 26: What We Know So Far
  • The Java Version Almanac Java25
  • Here’s Java 25, Ready to Perform to the Limit
  • What’s New in Project Leyden - JEP 514 and JEP 515 Explained

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表