跳到主要内容

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;
}
}
java

主要优点:

  • 精确控制类型层次结构
  • 增强代码安全性和可维护性
  • 与模式匹配完美配合
  • 支持接口和类的密封

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 -> "未知形状";
};
}
java

特点:

  • 更简洁的类型匹配语法
  • 穷尽性检查
  • 与密封类完美配合
  • 提高代码可读性

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());
java

改进:

  • 提供多种算法实现
  • 更好的性能
  • 更强的可预测性控制
  • 支持并行计算

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);
}
}
}
java

安全特性:

  • 细粒度的反序列化控制
  • 基于上下文的过滤规则
  • 防止反序列化漏洞
  • 可配置的安全策略

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");
}
java

目的:

  • 提高 JDK 的安全性
  • 改进 JDK 的可维护性
  • 促进使用公共 API
  • 简化 JDK 的演进

6. 删除实验性 AOT 和 JIT 编译器

移除了实验性的 AOT 和 JIT 编译器:

# 以下选项不再可用
java -XX:+UseAOTCompilation # 已移除
java -XX:+UseJITCompiler # 已移除
bash

影响:

  • 简化 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)
bash

特点:

  • 支持 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
);
// 绘制内容
}
});
}
}
java

改进:

  • 更好的性能
  • 更现代的图形栈
  • 改进的硬件加速
  • 更好的 HiDPI 支持

总结

JDK 17 作为一个 LTS 版本,带来了多项重要的改进和新特性。密封类的正式发布为 Java 的类型系统带来了重要的补充,而模式匹配 Switch 的预览则展示了 Java 语言未来的发展方向。

同时,在性能和安全性方面也有显著提升。增强的伪随机数生成器提供了更好的性能和可预测性,而上下文特定的反序列化过滤器则加强了应用程序的安全性。

作为一个 LTS 版本,JDK 17 将得到长期支持,建议企业用户考虑从之前的 LTS 版本(JDK 11)升级到 JDK 17。在升级过程中,需要注意:

  1. 测试应用程序的兼容性
  2. 评估新特性的使用机会
  3. 关注安全性改进
  4. 规划性能优化

对于开发者来说,这是一个学习和使用新特性的好机会,特别是密封类和模式匹配等新语言特性,它们可以帮助编写更安全、更简洁的代码。