JDK 17 LTS 版本重大特性详解
· 阅读需 8 分钟
Java 17 是继 JDK 11 之后的又一个长期支持版本(LTS),于2021年9月14日正式发布。作为一个 LTS 版本,它带来了许多重要的新特性和改进,这些特性将在未来很长一段时间内得到支持。本文将详细介绍 JDK 17 中的主要变更和新特性。
1. 密封类(正式发布)
密封类在 JDK 17 中正式成为标准特性:
public sealed interface Shape
permits Circle, Rectangle, Triangle {
double area();
}
public final class Circle implements Shape {
private final double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
// sealed 实现类
public sealed class Rectangle implements Shape
permits Square {
private final double width;
private final double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
}
// non-sealed 实现类
public non-sealed class Triangle implements Shape {
private final double base;
private final double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public double area() {
return 0.5 * base * height;
}
}
主要优点:
- 精确控制类型层次结构
- 增强代码安全性和可维护性
- 与模式匹配完美配合
- 支持接口和类的密封
2. 模式匹配 Switch(预览)
引入了 Switch 表达式的模式匹配预览特性:
public String getShapeDescription(Shape shape) {
return switch (shape) {
case Circle c ->
String.format("圆形,半径:%.2f,面积:%.2f",
c.getRadius(), c.area());
case Rectangle r ->
String.format("矩形,宽:%.2f,高:%.2f,面积:%.2f",
r.getWidth(), r.getHeight(), r.area());
case Triangle t ->
String.format("三角形,底:%.2f,高:%.2f,面积:%.2f",
t.getBase(), t.getHeight(), t.area());
default -> "未知形状";
};
}
特点:
- 更简洁的类型匹配语法
- 穷尽性检查
- 与密封类完美配合
- 提高代码可读性
3. 增强的伪随机数生成器
新增了增强的伪随机数生成器 API:
// 使用新的随机数生成器
RandomGenerator generator = RandomGenerator.getDefault();
// 生成随机数
int randomInt = generator.nextInt();
double randomDouble = generator.nextDouble();
// 使用特定算法的生成器
RandomGenerator xoshiro = RandomGenerator.of("Xoshiro256PlusPlus");
// 创建可重现的序列
RandomGenerator seeded = RandomGenerator.of("L64X128MixRandom")
.create(12345L);
// 并行流中使用
List<Double> randomNumbers = generator
.doubles()
.parallel()
.limit(1000)
.boxed()
.collect(Collectors.toList());
改进:
- 提供多种算法实现
- 更好的性能
- 更强的可预测性控制
- 支持并行计算
4. 上下文特定的反序列化过滤器
增强了反序列化的安全性:
// 创建过滤器
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
"java.base/*;!java.lang.Process");
// 应用过滤器
ObjectInputStream ois = new ObjectInputStream(inputStream);
ois.setObjectInputFilter(filter);
// 使用特定上下文的过滤器
public class SafeDeserializer {
public static <T> T deserialize(byte[] data, Class<T> type) {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bis);
// 设置特定于此上下文的过滤器
ois.setObjectInputFilter(info -> {
Class<?> clazz = info.serialClass();
if (clazz != null && !type.isAssignableFrom(clazz)) {
return ObjectInputFilter.Status.REJECTED;
}
return ObjectInputFilter.Status.ALLOWED;
});
try {
return type.cast(ois.readObject());
} catch (Exception e) {
throw new RuntimeException("反序列化失败", e);
}
}
}
安全特性:
- 细粒度的反序列化控制
- 基于上下文的过滤规则
- 防止反序列化漏洞
- 可配置的安全策略
5. 强封装 JDK 内部元素
进一步加强了 JDK 内部 API 的封装:
// 启动时指定允许访问的包
java --add-exports java.base/sun.security.x509=ALL-UNNAMED
// 反射访问示例
try {
// 这将失败,因为内部 API 被强封装
Class<?> clazz = Class.forName("sun.misc.Unsafe");
Field field = clazz.getDeclaredField("theUnsafe");
field.setAccessible(true);
Object unsafe = field.get(null);
} catch (Exception e) {
System.err.println("无法访问内部 API");
}
目的:
- 提高 JDK 的安全性
- 改进 JDK 的可维护性
- 促进使用公共 API
- 简化 JDK 的演进
6. 删除实验性 AOT 和 JIT 编译器
移除了实验性的 AOT 和 JIT 编译器:
# 以下选项不再可用
java -XX:+UseAOTCompilation # 已移除
java -XX:+UseJITCompiler # 已移除
影响:
- 简化 JDK 维护
- 专注于 Graal 项目
- 减少技术债务
- 提高代码质量
7. macOS/AArch64 端口
增加了对 macOS/AArch64 平台的支持:
# 检查 Java 版本和架构
java -version
# 输出示例:
# openjdk version "17" 2021-09-14
# OpenJDK Runtime Environment (build 17+35-2724)
# OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
特点:
- 支持 Apple M1 处理器
- 原生性能优化
- 完整的 JDK 功能支持
- 改进的能源效率
8. 新的 Mac 渲染管线
改进了 macOS 上的渲染管线:
// 启用新的渲染管线
System.setProperty("sun.java2d.metal", "true");
// 创建使用新渲染管线的窗口
public class MetalWindow extends JFrame {
public MetalWindow() {
setTitle("Metal 渲染示例");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 使用硬件加速的组件
add(new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// 启用抗锯齿
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
// 绘制内容
}
});
}
}
改进:
- 更好的性能
- 更现代的图形栈
- 改进的硬件加速
- 更好的 HiDPI 支持
总结
JDK 17 作为一个 LTS 版本,带来了多项重要的改进和新特性。密封类的正式发布为 Java 的类型系统带来了重要的补充,而模式匹配 Switch 的预览则展示了 Java 语言未来的发展方向。
同时,在性能和安全性方面也有显著提升。增强的伪随机数生成器提供了更好的性能和可预测性,而上下文特定的反序列化过滤器则加强了应用程序的安全性。
作为一个 LTS 版本,JDK 17 将得到长期支持,建议企业用户考虑从之前的 LTS 版本(JDK 11)升级到 JDK 17。在升级过程中,需要注意:
- 测试应用程序的兼容性
- 评估新特性的使用机会
- 关注安全性改进
- 规划性能优化
对于开发者来说,这是一个学习和使用新特性的好机会,特别是密封类和模式匹配等新语言特性,它们可以帮助编写更安全、更简洁的代码。