JDK 17 新特性
面试提问
"JDK 17 有哪些重要新特性?密封类是什么?"
JDK 17 简介
JDK 17 是 LTS(长期支持)版本,是 Java 生态的重要里程碑。
从 JDK 11 到 JDK 17 的重要特性
| 版本 | 重要特性 |
|---|---|
| JDK 12 | Switch 表达式(预览) |
| JDK 13 | 文本块(预览) |
| JDK 14 | Records(预览)、instanceof 模式匹配(预览) |
| JDK 15 | 文本块(正式)、密封类(预览) |
| JDK 16 | Records(正式)、instanceof 模式匹配(正式) |
| JDK 17 | 密封类(正式)、Switch 模式匹配(预览) |
1. 密封类(Sealed Classes)
概念
密封类限制哪些类可以继承或实现它。
// 密封类声明
public sealed class Shape
permits Circle, Rectangle, Triangle {
// 允许的子类必须在同一模块或包中
}
// permitted 子类必须是 final、sealed 或 non-sealed
public final class Circle extends Shape {
private final double radius;
}
public final class Rectangle extends Shape {
private final double width, height;
}
public non-sealed class Triangle extends Shape {
// non-sealed 允许进一步继承
}使用场景
// 模式匹配中使用
double area(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.width() * r.height();
case Triangle t -> 0.5 * t.base() * t.height();
};
}接口密封
public sealed interface Service permits HttpService, GrpcService {
void start();
}
public final class HttpService implements Service {
@Override
public void start() { }
}
public final class GrpcService implements Service {
@Override
public void start() { }
}2. instanceof 模式匹配
传统写法
if (obj instanceof String) {
String s = (String) obj; // 需要强制转换
System.out.println(s.length());
}模式匹配写法
if (obj instanceof String s) { // 直接声明变量
System.out.println(s.length());
}
// 条件判断
if (obj instanceof String s && s.length() > 5) {
System.out.println(s.toUpperCase());
}3. Switch 表达式
传统写法
String dayType;
switch (day) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
case FRIDAY:
dayType = "工作日";
break;
case SATURDAY:
case SUNDAY:
dayType = "周末";
break;
default:
dayType = "未知";
}Switch 表达式写法
// 箭头语法
String dayType = switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "工作日";
case SATURDAY, SUNDAY -> "周末";
default -> "未知";
};
// 带代码块
String dayType = switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {
System.out.println("努力工作");
yield "工作日"; // 使用 yield 返回值
}
case SATURDAY, SUNDAY -> "周末";
default -> "未知";
};4. 文本块(Text Blocks)
传统写法
String json = "{\n" +
" \"name\": \"张三\",\n" +
" \"age\": 25\n" +
"}";文本块写法
String json = """
{
"name": "张三",
"age": 25
}
""";特性
// 自动去除前导空格(以最左边为准)
String html = """
<html>
<body>
<p>Hello</p>
</body>
</html>
""";
// 行尾加 \ 避免换行
String text = """
这是一段很长的文字,\
实际上是一行。\
""";
// 使用 %s 占位符
String name = "张三";
String greeting = """
Hello, %s!
""".formatted(name);5. Records(记录类)
传统写法
public class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
@Override
public boolean equals(Object o) { ... }
@Override
public int hashCode() { ... }
@Override
public String toString() { ... }
}Record 写法
public record User(String name, int age) {
// 自动生成:构造器、getter、equals、hashCode、toString
}
// 使用
User user = new User("张三", 25);
user.name(); // "张三"(注意:不是 getName())
user.age(); // 25自定义方法
public record User(String name, int age) {
// 静态字段
public static final int ADULT_AGE = 18;
// 静态方法
public static User of(String name, int age) {
return new User(name, age);
}
// 实例方法
public boolean isAdult() {
return age >= ADULT_AGE;
}
// 紧凑构造器(验证)
public User {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负");
}
}
}6. 其他重要特性
随机数生成器增强
// 传统 Random
Random random = new Random();
// JDK 17 新 API
RandomGeneratorFactory<RandomGenerator> factory =
RandomGeneratorFactory.of("L32X64MixRandom");
RandomGenerator rng = factory.create();
// 获取所有算法
RandomGeneratorFactory.all()
.map(RandomGeneratorFactory::name)
.forEach(System.out::println);精简数字格式
// 传统写法
int million = 1000000;
// 下划线分隔
int million = 1_000_000;
// JDK 17:紧凑数字格式
NumberFormat format = NumberFormat.getCompactNumberInstance(
Locale.CHINA, NumberFormat.Style.SHORT);
format.format(1000); // "1千"
format.format(10000); // "1万"
format.format(1000000); // "100万"Vector API(孵化)
// SIMD 向量计算
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;
void vectorComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector va = FloatVector.fromArray(SPECIES, a, i);
FloatVector vb = FloatVector.fromArray(SPECIES, b, i);
va.mul(vb).intoArray(c, i);
}
}面试要点总结
| 问题 | 答案要点 |
|---|---|
| 密封类? | sealed + permits,限制继承 |
| instanceof 模式匹配? | if (obj instanceof String s) |
| Switch 表达式? | 箭头语法、yield 返回 |
| 文本块? | 三引号 """,多行字符串 |
| Record? | 自动生成 getter、equals、hashCode、toString |