首页 > 自考资讯 > 高考百科

从JDK8飞升到JDK17,再到未来的JDK21

小条 2024-06-27

2022 年,Spring 6 和Spring Boot 3 都将发布。在此之前,Java 社区总是“我要使用Java 8,无论新版本如何发布”。很少有人尝试升级。 这一次,Spring直接带来了大动作。 SpringBoot3和Spring6的最小依赖是JDK17。跳过JDK 8-16,直接升级到JDK 17。那么为什么是JDK 17呢?

背景

2022年,Spring6和SpringBoot3都会发布。在此之前,Java 社区总是这样说:“即使发布了新版本,我也会使用Java 8。”很少有人愿意升级。

这一次,Spring直接带来了大动作。 SpringBoot3和Spring6的最小依赖是JDK17。跳过JDK 8-16,直接升级到JDK 17。那么为什么是JDK 17呢?

为什么是JDK17

JDK 有许多新版本,其中JDK 18 和JDK 19 将于2022 年推出。 Spring 为什么选择JDK 17?

主要是Oracle官方公布的LTS版本,所以可以免费用于商业用途。所谓LTS是Long Term Support的缩写,是官方保证长期支持的版本。

a720bd3b562d4107aad0eb0e8e4f65c4~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720053403&x-signature=yld4j7xRDV9ZtBEqbXDYBV2ZKBc%3D

上图是Oracle官方提供的Oracle JDK支持时间表。如您所见,JDK 17 的支持期限最多到2029 年9 月。这8 年的免费商业使用期是善意的,以便用户可以自信、大胆地将自己的JDK 升级到JDK 17,具体取决于技术更新和迭代的速度(尽管JDK 8 更受长期支持并可扩展到12) 2030 年的几个月,JDK8 就是YYDS!)

从JDK 诞生到现在,主要长期支持的版本有JDK 7、JDK 8、JDK 11 和JDK 1。 JDK 17 是自Java 8 以来最重要的LTS 版本,是八年努力的结晶。由Java 社区工作。

Java8一直是Java社区的核心痛点。 JDK8 至今仍在使用,因为Java8 的支持寿命很长,此外还有lambda 表达式和可选类等许多功能。它代表了重视稳定的企业高管和重视变化的程序员之间的拉锯战。不升职!已经成为各大厂商的隐性选择。现在,这种平衡可能会被打破。因为Java世界的主导框架SpringBoot选择的是Java lts的最低支持版本,也就是最新的Java17。

现在让我们来看看Java 社区从JDK8 到JDK17 八年努力的成果。

从JDK8到JDK17的新特性

JDK9新特性(2017年9月)

模块化提供List.of()、Set.of()、Map.of()、Map.ofEntries()等工厂方法接口并支持私有方法可选类改进,多版本兼容Jar包垃圾收集器(例如支持HTTP2客户端API,JVM默认使用G1)

JDK10新特性(2018年3月)

局部变量的类型推断。和JS类似,可以通过var修改局部变量。编译后,将推断值的实际类型,并优化G1 的延迟线程本地握手。能够执行线程回调,而不强制全局VM 安全点、停止所有线程或停止单个线程而不停止任何线程可选的新orElseThrow() 方法类数据共享Unicode 语言标签扩展根证书主要功能:传递var key Word 实现局部变量类型Inference将Java语言变成了弱类型语言,将JVM的G1垃圾收集从单线程改为多线程并行,并且G1停顿时间减少。

JDK11新特性(2018年9月)(LTS版本)

为局部变量语法添加一些字符串处理方法。它还允许HTTP 客户端重写Lambda 参数,支持HTTP/1.1 和HTTP/2,并支持WebSockets 来运行单个Java 源文件。示例:java Test.javaZGC:可扩展ZGC是一种低延迟的垃圾收集器,可以认为是除了G1之外更细粒度的内存管理策略。持续分配和回收内存会产生大量内存碎片,因此需要碎片整理策略来防止内存空间碎片。该进程必须挂起引用内存的线程逻辑。世界'。只有排序完成后,线程逻辑才能继续执行。 (并行回收)数据收集框架支持TLS 1.3 协议Flight Recorder,并基于操作系统、JVM 和JDK 生成的事件,为Streams、Options 和Collection API 提供支持。 主要功能:主要针对JDK9 和JDK10 的改进进行流增强。集合和其他API,以及新的ZGC 垃圾收集器

JDK12新特性(2019年3月)

您可以切换表达式扩展并包含返回值。 新的NumberFormat 支持复数格式字符串的转换和缩进。 新方法Files.mismatch(Path, Path)Teeing Collector 支持Unicode 11Shenandoah GC,新GC。 算法G1的优化。收集器将GC 垃圾分为必需部分和可选部分。必需的部件会被回收,但可选的部件可能不会被回收。 Switch 表达式语法增强、G1 收集服务器优化以及新的Shenandoah GC 垃圾。采集算法

JDK13新特性(2019年9月)

开关表达式扩展。 switch表达式添加yield关键字来返回结果。如果没有返回结果,则使用中断文本块进行升级。引入文本块并可供使用。 '''三个双引号代表一个文本块。无需在文本块内使用换行转义字符。优化了Socket底层实现,引入了新方法NIOFileSystems.newFileSystem。ZGC得到增强,可以释放未使用的内存并对其进行长期标记。为了确保堆大小不低于配置的最小堆内存大小,可用堆内存空间将返回给操作系统。如果最大堆内存大小和最小堆内存大小设置为相同值,则不会释放内存并返回给操作系统。

主要特点:ZGC优化、释放操作系统内存并将NIO引入底层套接字实现

JDK14新特性(2020年3月)

模式匹配实例、类型匹配实例语法已简化,允许直接为对象赋值,如if (obj instance of String str)。如果obj是string类型,可以直接赋值给str变量,引入类似于Lombok的@Data注解的Record类型,并自动生成类似Lombok的构造函数、equals、getters等方法。 Switch 表达式- 标准化改进了NullPointerExceptions 提示信息,以打印抛出空指针异常的特定方法。如果在同一行代码上调用多个函数,则很难轻松排除异常,因为无法确定哪个函数会抛出异常。 CMS 垃圾收集器

JDK15新特性(2020年9月)

EdDSA 数字签名算法密封课程(封闭课程,预览版)。使用sealed关键字修改抽象类,将其限制为仅指定的子类或从抽象类继承,以避免抽象类的误用。MulticastSocket。

JDK16新特性(2021年3月)

允许在JDK C++ 源代码中使用C++14 功能。 ZGC性能优化,将ZGC线程堆栈处理从安全点移至并发阶段。为Unix 域套接字通道添加弹性元空间功能。 提供独立的Java 打包。 应用的jpackage工具是JDK16,对应JDK14和JDK15的一些特性的正式引入,比如instanceof模式匹配(模式匹配)和记录的引入。最终,JDK16成为最终版本。

JDK17新特性(2021年9月)(LTS版本)

免费Java 许可证JDK 17 取代JDK 11,并将成为下一个长期支持版本。在Spring 6 和Spring Boot 3 中,必须删除实验性AOT 和JIT 编译器才能恢复Always-Strict 模式浮点定义。密封类、抽象类实现限制、统一日志异步刷新日志先写入缓存,然后异步刷新。虽然JDK17是LTS版本,但它并没有像JDK8和JDK11那样引入很棒的功能。主要是对之前版本的整合和改进。

重要特性详解

Java 模块化

JPMS(Java 平台模块系统)是Java 9 版本的核心亮点。也称为Project Jig Show。模块是新的构造,就像我们已经有了包一样。使用新的模块化编程开发的应用程序可以被视为具有明确定义的边界和模块间依赖性的交互模块的集合。

JPMS 支持创建模块化应用程序和模块化JDK 源代码。 JDK 9 附带大约92 个模块(可能会在GA 版本中发生变化)。 Java 9 模块系统有一个“java.base”模块。这称为基本模块。这是一个独立的模块,不依赖于其他模块。默认情况下,所有其他模块都依赖于“java.base”。

在Java模块化编程中:

模块通常只是一个jar 文件,根目录中有一个module-info.class 文件。要使用模块,请将jar 文件包含在模块路径而不是类路径中。添加到类路径中的模块jar 文件是常规jar 文件,并且module-info.class 文件将被忽略。典型的module-info.java 类如下所示:

module helloworld { import com.alibaba.eight; } module test { require helloworld; } 总结:模块化的目的是能够拆分、重用、替换、重写一个jdk的不同组件,例如:如果您对Java 的语法不满意,Java gui 允许您用其他语言或其他语言的编译器替换javac,而无需模块化。不能每次改一个模块就重新编译整个jdk,然后发布整个sdk。模块化允许更有效的定制和部署。

本地变量类型推断

在Java 10 之前的版本中定义局部变量时。您必须在赋值的左侧指定显式类型,在赋值的右侧指定实现类型。

MyObject 值=new MyObject();

Java 10 提供了局部变量的类型推断,允许您使用var 声明变量。

var 值=new MyObject();

局部变量的类型推断消除了显式指定变量类型的需要,并引入了“var”关键字。

事实上,所谓的局部变量类型推断也是Java 10为开发者提供的语法糖。

我在代码中使用var 定义它,但虚拟机不知道这个var。在将Java文件编译成class文件的过程中,虚拟机会解析变量的实际类型,并将其替换为var。

HTTP客户端API-响应式流实现的HttpClient

Java 长期以来使用HttpURLConnection 进行HTTP 通信。然而,随着时间的推移,需求变得更加复杂,应用程序的要求也变得更高。在Java 11 之前,开发人员必须依赖功能丰富的库,例如Apache HttpComponents 和OkHttp。

事实证明,Java 9 版本包含一个HttpClient 实现作为实验性功能。随着时间的推移,这一点不断发展,现已成为Java 11 中的最终功能。 Java 应用程序现在可以通过HTTP 进行通信,而无需任何外部依赖项。

它是JDK11中正式发布的一个新的HTTP连接器,所以支持的功能还是比较新的。主要特点是:

完全支持HTTP 2.0 或HTTP 1.1。通过简单的块使用支持HTTPS/TLS。支持WebSocket。我们还可以为其他客户提供支持。 HttpClient用于异步返回数据。 WebSocket 支持是HttpClient 的一个优势。支持响应式流是HttpClient 的一大优势。

HttpClient 的NIO 模型、函数式编程、CompletableFuture 异步回调和响应式流为HttpClient 提供了强大的并发能力,从而带来非常高的性能和极低的内存占用。

语法糖

Stream API 改进

Collectors.teeing()

teeing 收集器作为静态方法Collectors:teeing 公开。该收集器将输入转发给其他两个收集器,并使用一个函数来组合它们的结果。

例子:

ListStudent list=Arrays.asList( new Student('唐一', 55), new Student('唐二', 60), new Student('唐三', 90));//平均总分String result=list .stream().collect(Collectors.teing( Collectors.averagingInt(Student:getScore), Collectors.summingInt(Student:getScore), (s1, s2) - s1 + ':' + s2));//最小和最大分数字符串result2=list.stream().collect(Collectors.teeing( Collectors.minBy(Comparator.comparing(Student:getScore)))), Collectors.maxBy(Comparator.comparing(Student:getScore)), (s1, s2) - s1.orElseThrow() + '第:章

添加Stream.toList方法(jdk16)

ListString list=Arrays.asList('1', '2', '3');//我之前是这样写的ListInteger oneList=list.stream() .map(Integer:parseInt) .collect(Collectors .toList () ) ;//现在可以这样写ListInteger TwoList=list.stream() .map(Integer:parseInt) .toList();

Switch表达式改进

箭头表达式支持(jdk12预览版jdk14标准)

此更改扩展了switch 语句,使其可以用作语句或表达式。您可以简单地使用箭头语法,而不是为每个case 块定义Break 语句。

boolean isWeekend=switch (day) { case MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY - false; case SATURDAY、SUNDAY - true; default - throw new IllegalStateException('非法日期条目: ' + day);}; switch (size) { case 1 - 'one'; case 2 - 'two'; default - 'unknown';};System.out.println(cn);//要使用此预览功能,应用程序必须明确告知JVM 在启动.

产量关键字(jdk13)

使用yield,您现在可以高效地从switch表达式返回值,并更轻松地实现策略模式。

public class SwitchTest { public static void main(String[] args) { var me='square'; var result=switch (操作) { case 'double' - { 产量我* 2; * i } 默认- i };

字符串

文本块改进(jdk13)

之前,我们将JSON 声明为字符串文字,以将其嵌入到我们的代码中。

String json='{\r\n' + '\'姓名\' : \'lingli\',\r\n' + '\'网站\' : \'https://www.alibaba.com/\'\ r\ n' + '}';

现在让我们使用字符串文字块编写相同的JSON。

String json='' { 'name' : 'Baeldung', 'website' : 'https://www.alibaba.com/' } ''';显然需要转义双引号或者添加回车符没有。文本块使编写嵌入式JSON 变得更容易,从而更易于阅读和维护。

更多的API

isBlank():如果字符串为空或仅包含空格(包括制表符),则返回true。请注意,与isEmpty() 不同,isEmpty() 仅当长度为0 时才返回true。 lines():将字符串拆分为字符串流。每个字符串包含一行。 strip():分别删除开头和结尾的空格。 stripLeading()/stripTrailing() 仅删除开头和结尾的空格。 Repeat(inttimes):返回重复原始字符串指定次数的字符串。 readString():允许您直接从文件路径读取字符串。 writeString(Path path):将字符串直接写入指定路径的文件中。 indent(int level):将字符串缩进指定的量。负值仅影响前导空格。 transform(Function f):将指定的lambda 应用于字符串。

点击查看原文,获得更多福利!

https://developer.aliyun.com/article/1084638?utm_content=g_1000364895

版权声明:本文内容由阿里云实名注册用户自愿贡献,版权归原作者所有,不承担相应的法律责任。具体规则参见《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您在该社区中发现您怀疑抄袭的内容,请填写侵权索赔表进行举报。一经核实,本社区将立即删除涉嫌侵权的内容。

版权声明:本文转载于网络,版权归作者所有。如有侵权,请联系本站编辑删除。

猜你喜欢