重要特性:主要是API的优化,如支持HTTP2的Client API、JVM采用G1为默认垃圾收集器。
重要特性:通过var关键字实现局部变量类型推断,使Java语言变成弱类型语言、JVM的G1垃圾回收由单线程改成多线程并行处理,降低G1的停顿时间。
重要特性:对于JDK9和JDK10的完善,主要是对于Stream、集合等API的增强、新增ZGC垃圾收集器。
重要特性:switch表达式语法扩展、G1收集器优化、新增Shenandoah GC垃圾回收算法。
重要特性:ZGC优化,释放内存还给操作系统、socket底层实现引入NIO。
JDK16相当于是将JDK14、JDK15的一些特性进行了正式引入,如instanceof模式匹配(Pattern matching)、record的引入等最终到JDK16变成了final版本。
虽然JDK17也是一个LTS版本,但是并没有像JDK8和JDK11一样引入比较突出的特性,主要是对前几个版本的整合和完善。
**模块化的目的,是让jdk的各个组件可以被分拆,复用和替换重写,**比如对java的gui不满意,可以自己实现一个gui,对java的语法不满意,可以把javac替换成其他语言和其他语言的编译器,比如kotlin和kotlinc等,没有模块化,几乎很难实现,每次修改某个模块,总不能把整个jdk给重新编译一遍,再发布一个整个sdk吧,模块化可以帮助更有效的定制化和部署
在Java 10中,提供了本地变量类型推断的功能,可以通过var声明变量:
var value = new MyObject();
作为JDK11中正式推出的新Http连接器,支持的功能还是比较新的,主要的特性有:
Collectors.teeing()
teeing 收集器已公开为静态方法Collectors::teeing。该收集器将其输入转发给其他两个收集器,然后将它们的结果使用函数合并
List list = Arrays.asList(new Student("唐一", 55),new Student("唐二", 60),new Student("唐三", 90));//平均分 总分
String result = list.stream().collect(Collectors.teeing(Collectors.averagingInt(Student::getScore),Collectors.summingInt(Student::getScore),(s1, s2) -> s1 + ":" + s2));//最低分 最高分
String result2 = list.stream().collect(Collectors.teeing(Collectors.minBy(Comparator.comparing(Student::getScore)),Collectors.maxBy(Comparator.comparing(Student::getScore)),(s1, s2) -> s1.orElseThrow() + ":" + s2.orElseThrow()
));System.out.println(result);
System.out.println(result2);
添加Stream.toList方法(jdk16)
List list = Arrays.asList("1", "2", "3");
//之前这样写
List oneList = list.stream().map(Integer::parseInt).collect(Collectors.toList());
//现在可以这样写
List twoList = list.stream().map(Integer::parseInt).toList();
支持箭头表达式(jdk12预览 jdk14标准)
此更改扩展了switch 语句以便它可以用作语句或表达式。不必为break每个 case 块定义一个语句,我们可以简单地使用箭头语法。
boolean isWeekend = switch (day) {case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false; case SATURDAY, SUNDAY -> true;default -> throw new IllegalStateException("Illegal day entry :: " + day);
};int size = 3;
String cn = switch (size) {case 1 -> "壹";case 2 -> "贰";case 3, 4 -> "叁";default -> "未知";
};
System.out.println(cn);
使用yield,我们现在可以有效地从 switch 表达式返回值,并能够更容易实现策略模式。
return:在程序函数中返回某个值,返回之后函数不在继续执行,彻底结束。
yield: 带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行,直到程序结束
public class SwitchTest {public static void main(String[] args) {var me = 4;var operation = "平方";var result = switch (operation) {case "加倍" -> {yield me * 2;}case "平方" -> {yield me * me;}default -> me;};System.out.println(result);}
}
例子:
def foo():print("starting...")while True:res = yield 4print("res:",res)g = foo()print(next(g))print("*"*20)print(next(g))
starting...4********************res: None4
1.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)
2.直到调用next方法,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环
3.程序遇到yield关键字,然后把yield想想成return,return了一个4之后,程序停止,并没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,
4.程序执行print("*"20),输出20个
5.又开始执行下面的print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,
6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 出4,然后程序停止,print函数输出的4就是这次return出的4.
文本块改进(jdk13)
早些时候,为了在我们的代码中嵌入 JSON,我们将其声明为字符串文字:
String json = "{\r\n" + "\"name\" : \"lingli\",\r\n" + "\"website\" : \"https://www.alibaba.com/\"\r\n" + "}";
现在让我们使用字符串文本块编写相同的 JSON :
String json = """ { "name" : "Baeldung", "website" : "https://www.alibaba.com/"
} """;
很明显,不需要转义双引号或添加回车。通过使用文本块,嵌入的 JSON 更易于编写,更易于阅读和维护。
JDK9: 设置G1为JVM默认垃圾收集器
JDK10:并行全垃圾回收器 G1,通过并行Full GC, 改善G1的延迟。目前对G1的full GC的实现采用了单线程-清除-压缩算法。JDK10开始使用并行化-清除-压缩算法。
JDK11:推出ZGC新一代垃圾回收器(实验性),目标是GC暂停时间不会超过10ms,既能处理几百兆的小堆,也能处理几个T的大堆。
JDK14 :删除CMS垃圾回收器;弃用 ParallelScavenge + SerialOld GC 的垃圾回收算法组合;将 zgc 垃圾回收器移植到 macOS 和 windows 平台
JDk 15 : ZGC (JEP 377) 和Shenandoah (JEP 379) 不再是实验性功能。默认的 GC 仍然是G1。
JDK16:增强ZGC,ZGC获得了 46个增强功能 和25个错误修复,控制stw时间不超过10毫秒