选用JDK17
oracle官方长期支持版本LTS 有 JDK8、JDK11、JDK17,JDK21据数据统计,JDK17的市场占有量已经超越了8和11,同时作为现代 Java 应用基石的 Spring 和 SpringBoot 都在新版本中摒弃了JDK8,支持 JDK17 ,后续的 JDK21 版本,除了虚拟线程比较亮眼外,其他特性相比 JDK17,感觉不痛不痒
文本块
文本块功能优化了字符串拼接,文本块指多行的字符串,使用连续的三个双引号来包围一段带换行的文字,它避免了换行转义的需要,并支持String.format
-
: , 置于行尾,用来将两行连接为一行
-
\s: 单个空白字符
String s="""SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` \sWHERE `CITY` = '%s' \ORDER BY `EMP_ID`, `LAST_NAME`;""";System.out.println(String.format(query, "沈阳"));
Switch 表达式增强
扩展switch语句,使其既可以作为语句使用,也可以作为表达式使用,并且两种形式都可以用“传统”或“简化”的作用域和控制流行为。同时添加了yield关键字,提供break 与switch返回值的功能
多值匹配
switch (name) {case "香蕉", "苹果", "桃" -> System.out.println("水果");case "黄瓜", "茄子" -> System.out.println("蔬菜");default -> System.out.println("其他品类");
}
分支返回yield
int result= switch (name) {case "香蕉", "苹果", "桃" -> 1;case "黄瓜", "茄子" -> 2;default -> {System.out.println("其他品类");yield 3;}
};
instanceof的模式匹配
instances 增加了模式匹配的功能,如果变量类型经过instances判断能够匹配目标类型,则对应分支中无需再做类型强转
if (o instanceof Integer i) {System.out.println(i);
}
else if (o instanceof String s) {System.out.println(s);
}
var 局部变量推导
对于某些可以直接推导出类型的局部变量,可以使用var进行声明,不可以对类中的变量,方法的参数使用var
var nums = new int[] {1, 2, 3, 4, 5};
var sum = Arrays.stream(nums).sum();
System.out.println("数组之和为:" + sum);
记录类 record
JDK17可以声明一种特殊的类record 。被reocrd定义的类代表的是一种不可变的常量,只能用来描述一种简单的不可变的数据结构,当然最为合适的是地理坐标x,y
public record Point(int x, int y) {}
这个类只能初始化设置属性值,初始化后,不允许修改属性值,用反射也不行
public class RecordTest {@Testpublic void getPoint() throws IllegalAccessException {Point p = new Point(10,20);for (Field field : p.getClass().getDeclaredFields()) {System.out.println(field);// 不允许通过反射修改值。// field.setAccessible(true);// field.set(p,30);}// 获取值 p.x p.ySystem.out.println(p.x()+"===="+p.y());}
}
record 原理
其实大致相当于给每个属性添加了private final声明。这样就不允许修改。
对于record类,同时还实现了toString,hashcode,equals方法,而这些方法都被声明成了final,进一步阻止应用定制record相关的业务逻辑
密封类 Sealed Classes
密封类就是用来限制每一个父类可以被哪些子类继承或者实现,并且是直接继承,可以理解为限制继承类
继承时的关键字
- final,表示这个子类不能再被继承了。
- non-sealed 表示这个子类没有密封特性,可以随意继承。
- sealed 表示这个子类有密封特性。再按照之前的方式声明他的子类
public sealed abstract class Shape permits Circle, Rectangle, Square {public abstract int lines();
}// 非密封子类,可以随意继承
public non-sealed class Square extends Shape{@Overridepublic int lines() {return 4;}
}
//final 子类,不可再被继承
public final class Circle extends Shape{@Overridepublic int lines() {return 0;}
}
// 密封子类,继续声明他所允许的子类。
public sealed class Rectangle extends Shape permits FilledRectangle {@Overridepublic int lines() {return 3;}
}public final class FilledRectangle extends Rectangle{@Overridepublic int lines() {return 0;}
}
GC调整
1 、ZGC 转正
ZGC 在之前已经做过介绍,是现在最为强大的一个垃圾回收器,自 JDK11 开始引入,从 JDK15 开始正式投入了使用。现在使用-XX:+UseZGC参数就可以快速使用 ZGC 。
ZGC 的具体实现其实也在版本升级过程中不断优化。在 JDK17 中使用指令 java -XX:+PrintFlagsFinal -version 可以简单看到,与 ZGC 相关的系统不稳定参数已经基本没有了。G1 的还有一大堆 这也说明 ZGC 的算法优化已经相当成熟了
随 ZGC 登场的,还有 RedHat 推出的Shenandoah 垃圾回收器。尽管 Oracle 一直比较抵触这个非官方推出的垃圾回收器,但是最终也还是将Shennandoah 垃圾回收器以可选的方案集成了进来。现在可以使用 -XX:+UseShenandoahGC 参数手动选择shennandoah
2 、废除 CMS
虽然 CMS作为 G1 之前唯一的一款并发的垃圾回收器,在相当长的时间里,都扮演者非常重要的角色。在最为经典的 JDK8 时代,尽管 CMS 一直没有作为默认垃圾回收器登场过,但是关于 G1 和 CMS 的比较以及取舍,一直都是业界津津乐道的话题。但是,随着 G1 垃圾回收器发展得更为完善,以及后续ZGC,shennandoah等现代垃圾回收器开始登场,过于复杂的 CMS 垃圾回收器还是退出了历史舞台。
在 JDK14 中,就彻底删除了 CMS 垃圾回收器。与 CMS 一起退场的,还有Parallel Scavenge +SerialOld的经典 GC 组合