JDK 17 一页速查卡
数据建模
3数据类 + 校验
record Range(int lo, int hi) {
Range {
if (lo > hi) throw new IllegalArgumentException();
}
}
隐式 final,继承 Record;组件是 private final,生成访问器、equals、hashCode、toString。不能加实例字段。
受控继承
sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double a) implements Shape {}
子类型必须 final / sealed / non-sealed;同模块(未命名模块同包)。permits 同文件可省略。
穷尽 switch(预览)
double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Square q -> q.side() * q.side();
};
}
17 仍是预览(JEP 406),编译运行都要 --enable-preview;守卫用 &&,不是 when;没有 record pattern。
语法表达
3判断即绑定
if (o instanceof String s && !s.isBlank()) {
return s.strip();
}
流作用域:&& 右侧可见,|| 右侧不可见;提前 return 后可见。泛型只能写 List<?>。
表达式 + yield
int code = switch (op) {
case ADD -> 1;
case SUB -> {
int v = 2;
yield v;
}
};
箭头不贯穿;表达式必须穷尽,enum 覆盖所有常量可省 default;null 选择器抛 NPE。
多行字符串
String sql = """
SELECT *
FROM users
WHERE id = ?
""";
附带空白按最小缩进剥离;\s 保留空格,行尾 \ 不换行;用 formatted 占位,没有插值。
运行时
3强封装与 add-opens
# 17:--illegal-access 已失效
java --add-opens java.base/java.lang=ALL-UNNAMED \
-jar app.jar
JEP 403 一律拒绝反射 JDK 内部;先升级库,再按包最小放行。ALL-UNNAMED 指 classpath。
默认与低停顿
# 默认 G1
java -XX:+UseZGC -Xmx8g -jar app.jar
java -XX:+UseShenandoahGC -Xmx8g -jar app.jar
G1 默认;ZGC / Shenandoah 15 转正;17 的 ZGC 是单代、无压缩指针;分代 ZGC 在 21。
依赖与 GC 日志
jdeps --jdk-internals -R app.jar
jdeprscan --release 17 --for-removal app.jar
java -Xlog:gc*:file=gc.log -jar app.jar
jdeps 只看静态引用;反射问题看 InaccessibleObjectException;PrintGCDetails 已弃用。
迁移与边界
317 已经没了
- RMI Activation:java.rmi.activation 与 rmid 移除(JEP 407),java.rmi 仍在
- --illegal-access:选项被忽略,封装一律生效(JEP 403)
- CMS / PermGen 参数:直接导致 JVM 无法启动
- AOT / Graal JIT:JEP 410 移除 jaotc 等实验工具
还在,但别新增依赖
- Security Manager:17 弃用但仍可安装(有警告);21 默认禁用;24 永久禁用
- Applet API:17 标记 forRemoval,类仍在 java.desktop
- Thread.stop / suspend / resume:17 可用,21 起抛 UOE
- finalize:长期弃用,改用 try-with-resources / Cleaner
17 的真实反馈
-XX:+UseConcMarkSweepGC:Unrecognized VM option-XX:MaxPermSize=256m:Unrecognized VM option--illegal-access=permit:警告并忽略-XX:+UseBiasedLocking:17 仅警告,21 才拒绝-XX:+PrintGCDetails:警告并映射到 -Xlog:gc*
4 个最容易记错的点TRAPS
JEP 406 需要 --enable-preview,class 文件是 61.65535;守卫写 case Circle c && c.r() > 0,不是 21 的 when;record pattern 在 17 完全不存在。
List / 数组组件的内容仍可变;数组的 equals 按引用比较,内容相同也可能 false。需要防御性拷贝与自定义 equals。
permits 只约束继承,不约束实例化;子类型必须 final / sealed / non-sealed,且同模块(未命名模块同包)。普通 switch 不会因为 sealed 自动穷尽。
17 只是弃用,默认仍允许 setSecurityManager,会打印终止性弃用警告;21 才默认抛 UOE,24 永久禁用。--illegal-access 在 17 已完全失效,只能 --add-opens。
继续深入NEXT
内容基于本机 JDK 17.0.13(Corretto)编译/运行验证;预览特性单独标注 --enable-preview。