前言
JDK 24 于2025年3月18日正式发布,下面看看都有哪些更新,新的语法都写了代码示例,内容有点多收藏起来慢慢看看。
我也来蹭一波流量😁😁😁
一、语言与编程模型改进
1. 模式匹配与原始类型支持
JEP 488 (第二次预览):允许在instanceof
和switch
中使用原始类型模式
消除基元类型在模式匹配中的限制,提升代码的简洁性和表达能力。
java
//------------switch
int num = 5;
switch (num) {
case 5 -> System.out.println("The number is 5");
case 10 -> System.out.println("The number is 10");
default -> System.out.println("The number is not 5 or 10");
}
//------- instanceof
if (obj instanceof int i) {
System.out.println("Integer value: " + i);
}
JEP 492(第三次预览):灵活的构造函数体
允许在构造函数中分序言和表述阶段,提升代码的可靠性。
旧有行为限制:在 Java 中,构造函数有严格的规则,构造函数的第一条语句必须是显式的构造函数调用(super() 或 this())。
如果省略,编译器会自动添加 super()。这确保了超类构造函数首先执行,以保证对象的安全初始化。
但这种方式在某些情况下会导致问题,例如在验证构造函数参数时,可能会导致不必要的计算。
本次更新就是打破这个限制啦!
java
public class FlexibleConstructorExample {
private final int id;
private final String name;
private final boolean active;
// 构造函数分为序言和表述阶段
public FlexibleConstructorExample(int id, String name, boolean active) {
// 序言阶段:进行参数验证和基本初始化
if (id <= 0) {
throw new IllegalArgumentException("ID must be positive");
}
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Name cannot be null or empty");
}
// 现在 `super` 和 `this` 之前可以写逻辑了
super();
// 表述阶段:正式初始化字段
this.id = id;
this.name = name;
this.active = active;
}
@Override
public String toString() {
return "FlexibleConstructorExample{" +
"id=" + id +
", name='" + name + '\'' +
", active=" + active +
'}';
}
public static void main(String[] args) {
FlexibleConstructorExample example = new FlexibleConstructorExample(1, "Alice", true);
System.out.println(example);
}
}
2. 简化入门编程
JEP 495(第四次预览):
简化源文件与实例主方法,允许学生或开发者无需复杂语法即可编写单类程序,降低学习门槛。
隐式声明类:
在简化的源文件中,开发者无需显式声明类。所有方法和字段都被视为隐式声明类的一部分,该类继承自 Object,且不实现任何接口。
这种方式减少了样板代码,使得初学者可以更专注于逻辑实现,而不是语言结构的复杂性56。
实例主方法:
主方法不再需要是 static 或 public,且可以不带参数。这使得主方法的定义更加灵活,符合初学者对程序入口的直观理解。
示例:
java
void main() {
println("Hello, World!");
}
这种写法比传统的 public static void main(String[] args) 更加简洁56。
简化控制台 I/O:
隐式声明类会自动导入一些常用的静态方法,如 println、print 和 readln,从而避免了繁琐的 System.out.println 写法。
示例:
java
void main() {
String name = readln("Please enter your name: ");
print("Pleased to meet you, ");
println(name);
}
这种方式进一步降低了初学者的学习难度。
模块导入声明:
结合 JEP 494(模块导入声明),隐式声明类可以自动从 java.base 模块导入所有公共顶级类和接口,减少了显式导入的需求。
java
import java.util.List;
void main() {
var authors = List.of("James", "Bill", "Bazlur", "Mike", "Dan", "Gavin");
for (var name : authors) {
println(name + ": " + name.length());
}
}
这种机制使得模块化库的使用更加便捷。
二、核心库与API增强
流处理与类文件操作
JEP 485 :流收集器(Stream Gatherers),支持自定义流中间操作,扩展Stream API
的功能。
java
import java.util.stream.*;
public class StreamGatherersExample {
public static void main(String[] args) {
// 自定义流收集器:将流中的字符串转换为大写并去重
Stream<String> stream = Stream.of("apple", "banana", "apple", "orange");
stream.gather(Gatherers.map(String::toUpperCase))
.gather(Gatherers.distinct())
.forEach(System.out::println);
}
}
JEP 484:类文件API,提供解析和生成类文件的标准接口,便于工具开发。
java
import java.nio.file.*;
import jdk.internal.classfile.*;
public class ClassFileExample {
public static void main(String[] args) throws Exception {
// 读取类文件
Path path = Paths.get("Example.class");
byte[] classFileBytes = Files.readAllBytes(path);
// 解析类文件
ClassModel classModel = Classfile.of().parse(classFileBytes);
// 输出类信息
System.out.println("Class Name: " + classModel.thisClass().name());
System.out.println("Methods:");
classModel.methods().forEach(method -> {
System.out.println(" " + method.methodName().stringValue());
});
}
}
并发与作用域值
JEP 487(第四次预览):作用域值(Scoped Values)
替代线程局部变量,优化虚拟线程间的不可变数据共享。
传统的线程局部变量(ThreadLocal)存在以下问题:
无约束的可变性:线程局部变量的值可以被任意修改,导致数据流难以追踪。 无界的生命周期:线程局部变量的值会一直存在,直到显式调用 remove 方法,容易导致内存泄漏。 昂贵的继承开销:子线程继承父线程的线程局部变量时,需要分配额外的存储空间,增加了内存开销28。
java
import java.util.concurrent.*;
public class ScopedValuesExample {
// 定义一个作用域值
private static final ScopedValue<String> USER_CONTEXT = ScopedValue.newInstance();
public static void main(String[] args) {
// 在主线程中绑定作用域值
ScopedValue.where(USER_CONTEXT, "Alice")
.run(() -> {
System.out.println("User in main thread: " + USER_CONTEXT.get());
// 启动一个虚拟线程
Thread.startVirtualThread(() -> {
System.out.println("User in virtual thread: " + USER_CONTEXT.get());
});
});
}
}
JEP 499(第四次预览):结构化并发
通过StructuredTaskScope
简化多线程任务管理,提升可维护性和可观测性。
bash
import java.util.concurrent.*;
import jdk.incubator.concurrent.*;
public class StructuredConcurrencyExample {
public static void main(String[] args) throws Exception {
try (var scope = new StructuredTaskScope<String>()) {
// 提交子任务
Future<String> task1 = scope.fork(() -> fetchData("Task 1"));
Future<String> task2 = scope.fork(() -> fetchData("Task 2"));
// 等待所有子任务完成
scope.join();
// 处理结果
System.out.println("Task 1 result: " + task1.resultNow());
System.out.println("Task 2 result: " + task2.resultNow());
}
}
private static String fetchData(String taskName) throws InterruptedException {
// 模拟耗时操作
Thread.sleep(1000);
return taskName + " completed";
}
}
三、安全与加密升级
抗量子加密算法
- JEP 496:基于模块格的抗量子密钥封装机制(ML-KEM),符合FIPS 204标准,防范量子计算攻击。
🤩抗量子加密算法,不知道这个加密算法我能用上不
- JEP 497:基于模块格的抗量子数字签名算法(ML-DSA),增强数据完整性和身份验证。
java
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class MLDSAExample {
public static void main(String[] args) throws Exception {
// 生成密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("MLDSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// 待签名的数据
String data = "Hello, World!";
byte[] dataBytes = data.getBytes();
// 签名
Signature signature = Signature.getInstance("MLDSA");
signature.initSign(privateKey);
signature.update(dataBytes);
byte[] signBytes = signature.sign();
String signatureBase64 = Base64.getEncoder().encodeToString(signBytes);
System.out.println("Signature: " + signatureBase64);
// 验证签名
signature.initVerify(publicKey);
signature.update(dataBytes);
boolean verified = signature.verify(signBytes);
System.out.println("Signature verified: " + verified);
}
}
安全机制调整
-
JEP 486:永久禁用安全管理器(Security Manager),简化安全模型以降低开发复杂度。
-
JEP 478(预览):密钥派生函数API,提升数据传输的加密安全性。
四、性能与运行时优化
垃圾收集器改进
-
JEP 404(实验性):分代Shenandoah垃圾收集器,提升吞吐量和内存利用率,未来计划设为默认模式。
-
JEP 490:移除ZGC的非分代模式,降低维护成本。
启动与内存优化
-
JEP 483:提前类加载与链接,通过缓存机制缩短启动时间(如Spring应用启动提速42%)。
-
JEP 450(实验性):紧凑对象头(64位架构下对象头从96-128位缩减至64位),减少堆内存占用。
五、平台与工具调整
弃用与移除
JEP 479:移除对Windows 32位x86平台的支持,简化构建和测试流程。
JEP 498 :弃用sun.misc.Unsafe
中的内存访问方法,并计划在JDK 26中彻底移除。
工具链优化
JEP 493:无需JMOD文件即可链接运行时镜像,减少JDK体积约25%。
在容器化部署、嵌入式系统、云原生应用 场景提升部署效率以及更轻的运行时支持。
六、其他重要更新
JEP 489:向量API(第九次孵化),持续优化数值计算性能,适配AI推理等场景。
java
import jdk.incubator.vector.*;
public class VectorAPIExample {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4};
int[] b = {1, 2, 3, 4};
int[] c = new int[4];
// 使用 128 位向量种类
var species = IntVector.SPECIES_128;
// 将数组转换为向量
var aVector = IntVector.fromArray(species, a, 0);
var bVector = IntVector.fromArray(species, b, 0);
// 执行向量加法
var cVector = aVector.add(bVector);
// 将结果写回数组
cVector.intoArray(c, 0);
System.out.println("Result: " + Arrays.toString(c)); // 输出: [2, 4, 6, 8]
}
}
JEP 491:虚拟线程同步优化,允许虚拟线程释放底层平台线程,提升并发扩展性。
虚拟线程释放平台线程:
在传统的虚拟线程模型中,虚拟线程在执行同步操作(如 synchronized 方法或代码块)时,会绑定到底层平台线程(Platform Thread),导致平台线程无法被其他虚拟线程使用,从而限制了并发扩展性。
JEP 491 允许虚拟线程在同步操作中释放底层平台线程,使得其他虚拟线程可以继续使用该平台线程,从而提高了资源利用率和并发性能311。
提升高并发场景的性能:
通过优化同步机制,JEP 491 显著减少了虚拟线程被固定到特定平台线程的情况,从而提高了虚拟线程在高并发场景下的处理能力。这对于需要处理大量并发请求的现代应用(如 Web 服务、实时数据处理等)尤为重要411。
简化并发编程:
该特性使得开发者无需手动管理虚拟线程的同步问题,减少了代码复杂性。开发者可以更专注于业务逻辑,而无需担心虚拟线程的资源利用率问题
java
import java.util.concurrent.*;
public class VirtualThreadSyncExample {
public static void main(String[] args) {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
synchronized (VirtualThreadSyncExample.class) {
System.out.println("Virtual thread executing synchronized block");
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
}
总结与展望
JDK 24通过多项实验性和预览特性为未来版本铺路,例如分代Shenandoah和紧凑对象头。同时,其安全性和性能优化(如抗量子加密和启动加速)直接回应了现代开发需求。
🎉希望有一天能见证传统加密方式全部取消,全部替换成抗量子加密,这一天什么时候能够到来呢😊,到时候手机 和 普通电脑是是也能提升到了无法想象的地步了呢