Java 25 中的 6 个新特性解读

本文聚焦 Java 25 中已永久化的 6 个特性:紧凑源文件与实例 main 方法、灵活的构造器主体、Scoped Values、模块导入声明、AOT 命令行易用性与方法剖析、分代 Shenandoah。通过简明说明与示例代码,帮助你快速把握其设计意图与落地用法。

1. 紧凑源文件与实例 main 方法

Java 25 支持"无显式类声明"的文件,并提供实例 main 方法与更短的 I/O API(java.lang.IO),降低入门成本。

  • 无需 class 声明,编译器会生成隐式、final、未命名类承载代码。
  • 无需冗长的 System.out.println,改用 IO.println
  • 自动导入 java.base 中常用类型(如集合/数学/时间)。

示例:

java 复制代码
void main() {
    IO.println("Hello, World!");
}

2. 灵活的构造器主体(Flexible Constructor Bodies)

以往构造器必须先调用 super()this(),才能执行校验或准备逻辑。Java 25 允许在不引用"正在构造的实例"的前提下,将校验逻辑放在显式父构造器调用之前,使代码更自然、更易读。

之前的常见写法:

java 复制代码
class Employee extends Person {
    Employee(String name, int age) {
        super(name, age);
        if (age < 18 || age > 67) {
            throw new IllegalArgumentException("Age out of range");
        }
    }
}

class Employee extends Person {
    Employee(String name, int age) {
        super(name, verifyAge(age));
    }

    private static int verifyAge(int value) {
        if (value < 18 || value > 67)
            throw new IllegalArgumentException("Age out of range");
        return value;
    }
}

Java 25 的更清晰写法:

java 复制代码
class Employee extends Person {
    Employee(String name, int age) {
        if (age < 18 || age > 67) {
            throw new IllegalArgumentException("Age out of range");
        }
        super(name, age);
    }
}

class BetterSub extends Super {
    final int x;
    BetterSub(int x) {
        this.x = x;
        super();
    }
    @Override void overriddenMethod() { System.out.println(x); }
}

3. Scoped Values

Scoped Values 是在结构化并发与虚拟线程场景下,传递"不可变上下文"的更合适机制。与 ThreadLocal 相比,它具有更清晰的词法作用域、更安全的不可变性以及更自然的并发传播语义。

关键点:

  • ScopedValue.where(...).run(...)/call(...) 的作用域内绑定并使用,不可中途变更。
  • 作用域之外派生的线程不会看到绑定,便于控制上下文生命周期。

示例(绑定请求上下文并在并发任务中使用):

java 复制代码
public class RequestContext {
    private final String requestId;
    public RequestContext(String requestId) { this.requestId = requestId; }
    public String requestId() { return requestId; }
}

public class ContextScope {
    public static final ScopedValue<RequestContext> CONTEXT = ScopedValue.newInstance();
}

public class RequestHandler {
    public void handleRequest(String rawRequestId) {
        RequestContext ctx = new RequestContext(rawRequestId);
        ScopedValue.where(ContextScope.CONTEXT, ctx).run(() -> {
            try {
                doWork();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
        });
    }

    void doWork() throws InterruptedException {
        try (var scope = new StructuredTaskScope<Void>()) {
            scope.fork(this::taskA);
            scope.fork(this::taskB);
            scope.join();
        }
    }

    void taskA() {
        RequestContext ctx = ContextScope.CONTEXT.get();
        System.out.println("taskA: requestId = " + ctx.requestId());
        helper();
    }

    void taskB() {
        RequestContext ctx = ContextScope.CONTEXT.get();
        System.out.println("taskB: requestId = " + ctx.requestId());
    }

    void helper() {
        RequestContext ctx = ContextScope.CONTEXT.get();
        System.out.println("helper: requestId = " + ctx.requestId());
    }
}

4. 模块导入声明(Module Import Declarations)

以模块维度一次性导入该模块导出的所有类型,减少样板代码并使依赖更直观。此机制是对现有导入方式的"补充",并非替代,注意名称冲突与显式性降低的风险。

示例:

java 复制代码
import module java.base

5. AOT 命令行易用性与方法剖析

两条 JEP 聚焦降低启动延迟与缩短 JIT 预热时间:

  • 命令行易用性(JEP 514):引入 -XX:AOTCacheOutput=<file>,内部生成并清理临时 AOT 配置文件,简化"记录+创建"的流程。
  • 方法剖析(JEP 515):将训练运行中的方法级执行剖析融入 AOT 缓存,让生产环境的 JIT 以更好的初始知识起步。

示例(生成 AOT 缓存输出):

bash 复制代码
java -XX:AOTCacheOutput=aot.cache -cp app.jar com.example.Main

6. 分代 Shenandoah

将 Shenandoah 从"非分代模式"推进到"分代模式"以生产可用,便于更高效地处理不同生命周期的对象。默认仍为单代模式,可通过参数启用分代:

bash 复制代码
java -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational

小结

Java 25 的六大永久特性着力改善开发体验(更简洁的源文件、更自然的构造器写法、模块层级导入),并在并发上下文传递(Scoped Values)与启动性能优化(AOT 易用性、方法剖析)方面显著增强;分代 Shenandoah 则为 GC 带来更具针对性的性能潜力。这些改进共同指向"更易用、更高效、更现代"的 Java。

相关推荐
稻草猫.3 小时前
文件 IO
java·笔记·后端·java-ee·idea
laopeng3013 小时前
基于Spring AI Deep Researcher Agent
java·人工智能·spring
掘金码甲哥3 小时前
有关CORS跨域访问,这事没完
后端
子豪-中国机器人4 小时前
《C++ STL 基础入门》教案
java·开发语言
java_t_t4 小时前
集合工具类
java·集合
消失的旧时光-19434 小时前
ScheduledExecutorService
android·java·开发语言
勇闯逆流河4 小时前
【C++】用红黑树封装map与set
java·开发语言·数据结构·c++
码事漫谈4 小时前
从外行到AI指挥官:你必须掌握的五大「程序员思维」
后端
Moonbit4 小时前
MoonBit 开发者激励计划开启|赢取价值 $20 Copilot 月卡权益!
后端