Java_JDK8到JDK21各版本发行时间及重要特性
- 背景
- JDK8新特性(2014年3月)
- JDK9新特性(2017年9月)
- JDK10新特性(2018年3月)
- JDK11新特性(2018年9月)(LTS版本)
- JDK12新特性(2019年3月)
- JDK13新特性(2019年9月)
- JDK14新特性(2020年3月)
- JDK15新特性(2020年9月)
- JDK16新特性(2021年3月)
- JDK17新特性(2021年9月)(LTS版本)
- JDK18新特性(2022年3月)
- JDK19新特性(2022年10月)
- JDK20新特性(2023年3月)
- JDK21新特性(2023年9月)(LTS版本)
背景
2022年Spring6和SpringBoot3相继推出,在此之前,Java社区一直是”新版任你发,我用Java 8″,不管新版本怎么出,很少有人愿意升级。
这一次,Spring 直接来了个大招,SpringBoot3和Spring6的最低依赖就是JDK17!跨过 JDK 8-16,直接升级到 JDK 17。那么为什么是 JDK 17呢?
为什么是JDK17这么多新版本的 JDK,而且2022年还会推出 JDK 18 和 JDK 19,为什么 Spring 选择了 JDK 17呢。
主要是因为他是一个 Oracle官宣可以免费商用的LTS版本,所谓 LTS,是 Long Term Support,也就是官方保证会长期支持的版本。
JDK 17 最多可以支持到 2029 年 9 月份。按照技术更新迭代的速度,这次免费商用 8 年可谓是良苦用心,为的就是让使用者放心大胆地将 JDK 升级到 JDK 17(不过JDK 8 支持的时间更长,可以延长到 2030 年 12 月,JDK8可谓是YYDS!)
从 JDK 诞生到现在,还在长期支持的版本主要有 JDK 7、JDK 8 、JDK 11以及 JDK 1,JDK 17 将是继 Java 8 以来最重要的LTS版本,是 Java 社区八年努力的成果。
一直以来,Java8 都是 Java 社区心头的痛,Java8提供了很多特性,比如Lambda 表达式、Optional 类,加上Java8超长的支持时间,都导致了JDK8的使用至今。它代表着以稳定性为主的企业管理层与拥抱变化为主的程序猿之间的拉锯战。不升!成为各大厂心照不宣的选择。现在,这种平衡或将打破。因为 Java 届的霸主框架 SpringBoot,选择了最小支持的 Java lts 版本,就是最新的 Java17。
那么接下来,让我们看看,从JDK8到JDK21有哪些新特性?
JDK8新特性(2014年3月)
- Lambda表达式
- 新的日期API
- 引入Optional
- 使用Base64
- 接口的默认方法和静态方法
- 新增方法引用格式
- 新增Stream类
- 注解相关的改变
- 支持并行(parallel)数组
- 对并发类(Concurrency)的扩展。
Java的发展历史 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。Java8 商用收费从2019年1月份开始,Oracle JDK开始对JavaSE 8 之后的版本开始进行商用收费,确切的说是 8u201/202 之后的版本。
JDK9新特性(2017年9月)
- 模块化
- 提供了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法
- 接口支持私有方法
- Optional 类改进
- 多版本兼容Jar包
- JShell工具
- try-with-resources的改进
- Stream API的改进
- 设置G1为JVM默认垃圾收集器
- 支持http2.0和websocket的API
重要特性:主要是API的优化,如支持HTTP2的Client API、JVM采用G1为默认垃圾收集器。
JDK10新特性(2018年3月)
- 局部变量类型推断,类似JS可以通过var来修饰局部变量,编译之后会推断出值的真实类型
- 不可变集合的改进
- 并行全垃圾回收器 G1,来优化G1的延迟
- 线程本地握手,允许在不执行全局VM安全点的情况下执行线程回调,可以停止单个线程,而不需要停止所有线程或不停止线程
- Optional新增orElseThrow()方法
- 类数据共享
- Unicode 语言标签扩展
- 根证书
重要特性:通过var关键字实现局部变量类型推断,使Java语言变成弱类型语言、JVM的G1垃圾回收由单线程改成多线程并行处理,降低G1的停顿时间。
JDK11新特性(2018年9月)(LTS版本)
- 增加一些字符串处理方法
- 用于 Lambda 参数的局部变量语法
- Http Client重写,支持HTTP/1.1和HTTP/2 ,也支持 websockets
- 可运行单一Java源码文件,如:java Test.java
- ZGC:可伸缩低延迟垃圾收集器,ZGC可以看做是G1之上更细粒度的内存管理策略。由于内存的不断分配回收会产生大量的内存碎片空间,因此需要整理策略防止内存空间碎片化,在整理期间需要将对于内存引用的线程逻辑暂停,这个过程被称为”Stop the world”。只有当整理完成后,线程逻辑才可以继续运行。(并行回收)
- 支持 TLS 1.3 协议
- Flight Recorder(飞行记录器),基于OS、JVM和JDK的事件产生的数据收集框架
- 对Stream、Optional、集合API进行增强
重要特性:对于JDK9和JDK10的完善,主要是对于Stream、集合等API的增强、新增ZGC垃圾收集器。
JDK12新特性(2019年3月)
- Switch 表达式扩展,可以有返回值
- 新增NumberFormat对复杂数字的格式化
- 字符串支持transform、indent操作
- 新增方法Files.mismatch(Path, Path)
- Teeing Collector
- 支持unicode 11
- Shenandoah GC,新增的GC算法
- G1收集器的优化,将GC的垃圾分为强制部分和可选部分,强制部分会被回收,可选部分可能不会被回收,提高GC的效率
重要特性:switch表达式语法扩展、G1收集器优化、新增Shenandoah GC垃圾回收算法。
JDK13新特性(2019年9月)
- Switch 表达式扩展,switch表达式增加yield关键字用于返回结果,作用类似于return,如果没有返回结果则使用break
- 文本块升级 “”” ,引入了文本块,可以使用”””三个双引号表示文本块,文本块内部就不需要使用换行的转义字符
- SocketAPI 重构,Socket的底层实现优化,引入了NIO
- FileSystems.newFileSystem新方法
- ZGC优化,增强 ZGC 释放未使用内存,将标记长时间空闲的堆内存空间返还给操作系统,保证堆大小不会小于配置的最小堆内存大小,如果堆最大和最小内存大小设置一样,则不会释放内存还给操作系统
重要特性:ZGC优化,释放内存还给操作系统、socket底层实现引入NIO。
JDK14新特性(2020年3月)
- instanceof模式匹配,instanceof类型匹配语法简化,可以直接给对象赋值,如if(obj instanceof String str),如果obj是字符串类型则直接赋值给了str变量
引入Record类型,类似于Lombok 的@Data注解,可以向Lombok一样自动生成构造器、equals、getter等方法;
Switch 表达式-标准化 - 改进 NullPointerExceptions提示信息,打印具体哪个方法抛的空指针异常,避免同一行代码多个函数调用时无法判断具体是哪个函数抛异常的困扰,方便异常排查;
- 删除 CMS 垃圾回收器
JDK15新特性(2020年9月)
- EdDSA 数字签名算法
- Sealed Classes(封闭类,预览),通过sealed关键字修饰抽象类限定只允许指定的子类才可以实现或继承抽象类,避免抽象类被滥用
- Hidden Classes(隐藏类)
- 移除 Nashorn JavaScript引擎
- 改进java.net.DatagramSocket 和 java.net.MulticastSocket底层实现
JDK16新特性(2021年3月)
- 允许在 JDK C ++源代码中使用 C ++ 14功能
- ZGC性能优化,去掉ZGC线程堆栈处理从安全点到并发阶段
- 增加 Unix 域套接字通道
- 弹性元空间能力
- 提供用于打包独立 Java 应用程序的 jpackage 工具
- JDK16相当于是将JDK14、JDK15的一些特性进行了正式引入,如instanceof模式匹配(Pattern matching)、record的引入等最终到JDK16变成了final版本。
JDK17新特性(2021年9月)(LTS版本)
- Free Java License 根据Oracle官方发布的最新Free Java License,Oracle JDK 可以免费用于生产环境。
- JDK 17 将取代 JDK 11 成为下一个长期支持版本
- Spring 6 和 Spring Boot 3需要JDK17
- 移除实验性的 AOT 和 JIT 编译器
- 恢复始终执行严格模式 (Always-Strict) 的浮点定义
- 正式引入密封类sealed class,限制抽象类的实现
- 统一日志异步刷新,先将日志写入缓存,然后再异步刷新
- 虽然JDK17也是一个LTS版本,但是并没有像JDK8和JDK11一样引入比较突出的特性,主要是对前几个版本的整合和完善。
JDK18新特性(2022年3月)
- 指定 UTF-8 作为标准 Java API 的默认字符集。通过此更改,依赖于默认字符集的 API 将在所有实现、操作系统、区域设置和配置中保持一致。
- 引入一个简单的 Web 服务器。提供一个命令行工具,来启动一个只提供静态文件的最小网络服务器,它没有 CGI 或类似 servlet 的功能可用。该工具用于原型设计、临时编码和测试目的,尤其是在教学环境中。
- 支持在 Java API 文档中加入代码片段。为 JavaDoc 的 Standard Doclet 引入一个 @snippet 标记,以简化 API 文档中嵌入示例源代码的难度。
- 用方法句柄重新实现核心反射。在 java.lang.invoke 的方法句柄之上,重构 java.lang.reflect 的方法、构造函数和字段,使用方法句柄处理反射的底层机制将减少 java.lang.reflect 和 java.lang.invoke 两者的 API 维护和开发成本。
- Vector API(第三孵化器)。引入一个 API 来表达向量计算,这些计算在运行时可以编译为支持的 CPU 架构上的最佳向量指令,从而实现优于等效标量计算的性能。
- 互联网地址解析 SPI。定义用于主机名和地址解析的服务提供者接口 (SPI),以便java.net.InetAddress可以使用平台内置解析器以外的解析器。
- 外部函数和内存 API(第二孵化器)。引入了一个新 API, Java 程序可以通过它与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即 JVM 外的代码),并安全地访问外部内存(即不由 JVM 管理的内存),外部函数和内存 API 使 Java 程序能够调用本机库并处理本机数据,而不具有 JNI 的脆弱性和危险。
- switch 模式匹配表达式。使用 switch 表达式和语句的模式匹配以及对模式语言的扩展来增强 Java 编程语言。将模式匹配扩展到 switch 允许针对多个模式测试表达式,每个模式都有特定的操作,可以简洁安全地表达复杂的面向数据的查询。
- 弃用 Finalization 功能。Java 1.0 中引入的 Finalization 旨在帮助避免资源泄漏问题,然而这个功能存在延迟不可预测、行为不受约束,以及线程无法指定等缺陷,导致其安全性、性能、可靠性和可维护性方面都存在问题,因此将其弃用,用户可选择迁移到其他资源管理技术,例如try-with-resources 语句和清洁器。
重点是使语言更加直观和易于访问,鼓励所有技能水平的程序员使用 Java。新版本肯定是一次重大更新,具有简单的 Web 服务器、模式匹配改进和默认 UTF-8 等新功能。此外,随着 Java API 文档中的代码片段和互联网地址解析 SPI 等变化,重点更多地放在改善新手和专家等用户体验上。
JDK19新特性(2022年10月)
- 结构化并发。当前还处于孵化阶段,旨在通过结构化并发 API 简化多线程编程。这种并发性将不同线程中运行的多个任务视为单个工作单元,从而简化错误处理、提高可靠性和可观察性。这个功能来自 Project Loom,它引入了一个新的轻量级并发模型。
- 记录模式,这一功能目前也处于预览版,主要是用来解构记录值。记录模式和类型模式可以被嵌套,以实现强大的、具有声明性的和可组合的数据导航和处理形式。该提案的目标包括扩展模式匹配,用以表达更复杂的、可组合的数据查询,同时不改变类型模式的语法或语义。该提案建立在 2021 年 3 月在 JDK 16 中交付的模式匹配的基础上。未来,Oracle 可能会要求对记录模式进行扩展,使之具备数组模式、Vararg 模式。记录模式是 Project Amber 的一部分,该项目旨在探索和孵化较小的、面向生产力的 Java 功能。
- 外部函数和内存 API 的预览版。通过引入一个 API,Java 程序可以与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存(即不由 JVM 管理的内存),该 API 使 Java 程序能够调用本地库并处理本机数据,而不会出现 Java 本地接口(JNI)的危险和脆弱。外部函数和内存 API 结合了两个早期的孵化 API:外部内存访问 API 和外部链接器 API。外部函数和内存 API 曾在 JDK 17 中孵化,而后在 JDK 18 中重新孵化。该提案的目标包括易用性、性能、通用性和安全性。
- 虚拟线程的预览版。这是一种轻量级的线程,大大减少了编写、维护和观察高吞吐量并发应用的工作量。可以以简单的 thread-per-request 风格编写的服务器应用程序能够以接近最佳的硬件利用率进行扩展,通过使用 java.lang Thread API 现有代码能够以最小的改动采用虚拟线程,并基于现有的 JDK 工具对虚拟线程进行故障诊断、调试和分析。本提案的目标不是要改变 Java 的基本并发模型,也不是要在 Java 语言或 Java 库中提供新的数据并行结构。它的目标也不是去除线程的传统实现,或默默地将现有的应用程序迁移到使用虚拟线程。这项功能也是 Project Loom 的一部分。
- 对 switch 表达式和语句的模式匹配进行了第三次预览。这项功能以前在 JDK 17、JDK 18 中进行过预览。这一次在 JDK 19 中将进一步细化功能,包括用 switch 块中的 when 子句替换受保护的模式。另外,当选择器表达式的值为 null 时,模式切换的运行时语义与传统的语义更加一致。这项功能也是 Amber 项目的一部分。
- Vector API 的第四次孵化,将表达向量计算,在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于等效标量计算的性能。该 API 的开发者使用 HotSpot 自动矢量器,可获得了一种在 Java 中编写复杂的向量算法的方法,但有一个用户模型,使向量化更可预测和稳健。Vector API 先前已被纳入 JDK 16、JDK 17 和 JDK 19。在最新的 JDK 19 中,官方为该功能增加了两个跨道向量操作,即压缩和扩展,以及一个互补的向量掩码压缩操作。压缩向量操作将由掩码选择的源向量的通道按通道顺序映射到目标向量,而扩展操作则做相反的操作。压缩操作在过滤查询结果时非常有用。
- 通过 Linux/RISC-V 移植,目前这一功能已正式可用。Java 将获得对硬件指令集的支持,该指令集已经被广泛的语言工具链所支持。RISC-V 实际上是一系列相关的 ISA。Linux/RISC-V 端口将只支持 RISC-V 的 RV64GV 配置,这是一个包括矢量指令的通用 64 位 ISA。Java 的开发者可能会在将来考虑其他 RISC-V 的配置。
根据官方发布的公告显示,Java 19 版本带来了七大主要功能更新,包括结构化并发、记录模式、外部函数和内存 API 的预览,以及对开源的 Linux/RISC-V 指令集架构(ISA)的支持。除了 Linux/RISC-V 功能,所有的功能都处于预览或孵化阶段。
JDK20新特性(2023年3月)
- 作用域值(孵化器)
- Record 模式匹配(第二次预览)
- switch 的模式匹配(第四次预览)
- 外部函数和内存 API(第二个预览版)
- 虚拟线程(第二个预览版)
- 结构化并发(第二孵化器)
- Vector API(第五孵化器)
Java 20 共带来 7 个新特性功能,其中三个是孵化提案,孵化也就是说尚在征求意见阶段,未来可能会删除此功能。
JDK21新特性(2023年9月)(LTS版本)
- 序列集合。该 JEP 提议引入“一个新的接口族,用于表示集合的概念,这些集合的元素按照预定义的序列或顺序排列,它们是作为集合的结构属性。”这一提案的动机是由于集合框架中缺乏预定义的顺序和统一的操作集。
- 分代 ZGC。通过扩展Z垃圾回收器(ZGC)来维护年轻对象和年老对象的独立生成,从而提高应用程序性能。这将使ZGC能够更频繁地收集年轻对象——这些对象往往英年早逝。
- 记录模式。使用记录模式(Record Patterns)增强Java编程语言,以解构记录值。可以嵌套记录模式和类型模式,以实现功能强大、声明性和可组合形式的数据导航和处理。
- switch 模式匹配。通过switch表达式和语句的模式匹配来增强Java编程语言。通过将模式匹配扩展到switch,可以针对多个模式测试表达式,每个模式都有一个特定的操作,从而可以简洁、安全地表达复杂的面向数据的查询。
- 虚拟线程。将虚拟线程(Virtual Threads)引入Java平台。虚拟线程是轻量级线程,可以显著减少编写、维护和观察高吞吐量并发应用程序的工作量。
- 弃用Windows 32位x86移植,并打算在将来的版本中将其删除。
- 准备禁止动态加载代理。将代理动态加载到正在运行的JVM中时发出警告。这些警告旨在让用户为将来的版本做好准备,该版本默认情况下不允许动态加载代理,以提高默认情况下的完整性。在启动时加载代理的可服务性工具不会导致在任何版本中发出警告。
- 密钥封装机制 API。介绍一种用于密钥封装机制(Key Encapsulation Mechanism,简称KEM)的API,这是一种使用公钥加密来保护对称密钥的加密技术。
- 字符串模板(预览)。使用字符串模板(String Templates)增强Java编程语言。字符串模板通过将文本与嵌入的表达式和模板处理器耦合来生成专门的结果,从而补充Java现有的字符串文本和文本块。这是一个预览语言功能和API。
- 外部函数和内存 API(第三次预览)。引入API,Java程序可以通过该API与Java运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即JVM外部的代码),并通过安全地访问外部内存(即不受JVM管理的内存),API使Java程序能够调用本机库并处理本机数据,而不会出现JNI的脆弱性和危险性。这是一个预览API。
- 未命名模式和变量(预览)。使用未命名模式和未命名变量来增强Java语言,未命名模式匹配记录组件而不说明组件的名称或类型,未命名变量可以初始化但不使用。两者都用下划线字符_表示。这是一个预览语言功能。
- 未命名类和实例主方法(预览)。发展Java语言,使学生无需理解为大型程序设计的语言功能即可编写第一个程序。学生们不用使用单独的Java方言,就可以为单类程序编写精简的声明,然后随着技能的发展,无缝地扩展程序,使用更高级的功能。这是一个预览语言功能。
- 作用域值(预览)。引入作用域值,这些值可以在不使用方法参数的情况下安全有效地共享给方法。它们优先于线程化局部变量,尤其是在使用大量虚拟线程时。这是一个预览API。
- 结构化并发(预览)。通过引入用于结构化并发(Structured Concurrency)的API来简化并发编程。结构化并发将在不同线程中运行的相关任务组视为单个工作单元,从而简化错误处理和消除,提高可靠性,并增强可观察性。这是一个预览API。
- Vector API(孵化器第六阶段)
根据发布的规划,这次发布的 JDK 21 将是一个长期支持版(LTS 版)。LTS 版每 2 年发布一个,上一次长期支持版是 21 年 9 月发布的 JDK 17。