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。

相关推荐
IT_陈寒7 分钟前
Vue的v-for不听话?我被这个Key的坑整懵了
前端·人工智能·后端
2601_9638699514 分钟前
【计算机毕业设计】基于Java的相框定制系统的设计与实现
java·开发语言·课程设计
众人皆醒我独醉31 分钟前
训练加速实战:Flash Attention、Gradient Checkpointing 与数据流水线
后端·面试·gpu
阿黎梨梨36 分钟前
Next.js 全栈开发:从 SPA 的痛点到 SSR 的破局之道
前端·后端
名字还没想好☜1 小时前
Go 的 unsafe.Pointer 实战:零拷贝 []byte↔string 转换与三条铁律
开发语言·后端·golang·go·unsafe
老孙讲技术1 小时前
周末档期厨房爆单,带宽账单也爆了——不是直播难,是主码流 + always 计划在烧钱
后端·物联网
于烛1 小时前
为什么hasNext() 对只有一个元素的集合返回 true?90%初学者都有的疑问
java
老孙讲技术1 小时前
校园开放日前夜才说要「全校透明」?我用轻应用把 9 路教室预览和回放嵌进了校园后台
后端·物联网
wuminyu1 小时前
JVM利用io_uring优化堆外内存性能原理剖析
java·linux·c语言·jvm·c++
Python私教2 小时前
AI Agent 可观测性实战:从 correlationId 到失败时间线
人工智能·后端