您的位置 首页 java

Java在过去7年的发展(从Java 8到Java 17)

本文基于Wejdi的《How java Has Advanced In The Past 6 Years (From Java 8 to Java 15)》翻译整理而来,在原作基础上作了扩充,汇集了 Java 从2014年的版本8到2021年的版本17长达7年之间各版本的重要新增特性和修改,全文一万多字,可以说是“史诗级”的(又臭又长,TL;DR),感兴趣的同学可以快速翻阅,文末(或置顶评论中)也会给出一个查看各版本特性的好地方(来龙去脉解释的比较清楚)。

Java 发布周期

直到版本8,Java每3年发布一次版本,所以基本上每个版本都有很多功能。

因此,新版本的Java都很复杂,并且由于包含的更改数量较多,开发人员升级其应用程序也很复杂。

而这种更新速度已经跟不上时代,一切都在越来越快地进行!因此,Java架构师决定每6个月发布一个版本(因此有一个固定的时间表)。

在每个版本中,所有就绪的功能都被合并,那些未准备好的功能将在下一个版本中提供(不再有后期版本)。

Java 8 最重要的特性和示例

1) Java 语言 中的新功能

forEach()方法
Java 8 在 java.lang.Iterable 接口中引入了 forEach 方法,因此在编写代码时,我们只关注业务逻辑。

Lambda Expression
Java 8 最大的新特性是对 Lambda 表达式 (Project Lambda)的语言级支持。
Lambda 表达式语法为(参数)->(正文)。

接口的默认和 静态方法
在Java 8之前,Java中的接口只能有抽象的方法。默认情况下,接口的所有方法都是public和 abstract 的。而Java 8 允许接口具有缺省方法和静态方法。

默认方法 我们在接口中使用默认方法的原因是允许开发人员向接口添加新方法,而不会影响已经实现这些接口的类

静态方法 在接口中类似于默认方法,除了我们不能在实现这些接口的类中重写这些方法。
例如,新的 Stream 接口上有许多静态方法。
这使得”helper”方法更容易找到 ,因为它们可以直接位于接口上,而不是不同的类,如 Stream Util或Streams。

功能接口( Functional Interface

在Java 8中, 功能接口被定义为只有一个抽象方法的接口 。这甚至适用于使用以前版本的Java创建的接口。
Java 8在java.util. Function 软件包中附带了几个新的功能接口:
-Function – 获取类型为 T 的对象并返回 R.
-Supplier – 仅返回类型 T 的对象。
-Predicate – 返回基于 T 类型输入的 布尔 值。

-Consumer – 使用类型 T 的给定对象执行操作

方法引用(Method References)
方法引用是一种特殊类型的 lambda 表达式 ,它们通常用于通过引用现有方法创建简单的 lambda 表达式。
有以下4种方法引用:
– 静态方法
– 特定对象的实例方法

– 特定类型的任意对象的实例方法
– 构造函数

示例 :

2)Java库 中的新功能

流API(Stream API)
流接口是Java 8的基本组成部分。

我们可以使用Java Stream API来实现内部迭代,这更好,因为java框架控制迭代。

Stream API 支持 map/ filter /reduce 模式及延迟执行,构成了 Java 8 函数式编程的基础(以及 lambda)。

出于性能原因,还有相应的基元流(IntStream、DoubleStream 和 LongStream)。

在 Java 8 中,集合接口有两种方法来生成流:
-stream():返回一个将集合视为其源的顺序流。

-parallelStream() : 返回将集合视为其源的并行流。

可选的(Optional)
Java 8 在 java.util 包中附带了 Optional 类,用于避免null返回值(从而避免 NullPointerException)。

如果存在值,则 isPresent() 将返回 true,get() 将返回该值。

流终端操作会返回可选对象,其中一些方法是:
-Optional reduce(Binary Operator accumulator)
-Optional min(Comparator<? super T> comparator)
-Optional max(Comparator<? super T> comparator)
-Optional findFirst()
-Optional findAny()

日期/时间 API(Date/Time API)
在 Java 8 中,引入了新的日期时间 API,以涵盖旧日期时间 API 的以下缺点:
线程 不安全
-设计不佳

-时区处理困难

Java 8 Date Time API 由以下包组成:

  1. java.time 包:这是新的 Java Date Time API 的 基本包 。例如LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration等。所有这些类都是不可变的和线程安全的。
  2. java.time.chrono 包:此软件包为 非 ISO 日历系统 定义了通用 API。我们可以扩展抽象年代学类来创建我们自己的日历系统。
  3. java.time.temporal 包:此包包含 临时对象 ,我们可以使用它来查找与日期/时间对象相关的特定日期或时间。例如,我们可以使用这些来找出该月的第一天或最后一天。您可以轻松识别这些方法,因为它们始终具有格式”withXXX”。
  4. java.time.zone 包:此包包含用于 支持不同时区 及其规则的类。

Java 9 最重要的特性和示例

Java 9包括对数千兆字节堆的更好支持、更好的本机代码集成、不同的默认垃圾回收器(G1,用于”更短的响应时间”)和自调优 JVM

Java 平台模块化(Project Jigsaw)
模块是一个命名的,自我描述的代码和数据的集合。Java 9 中的模块化是对 Java 的一次重大改进。它是一种新型的Java编程组件,可用于收集Java代码(类和包)。该项目的主要目标是轻松地将应用程序扩展到小型设备。在Java 9中, JDK 本身已经分成了一组模块,以使其更加轻量级。它还允许我们开发模块化应用程序。

● J shell :交互式 Java REPL
JShell 是一个 REPL(Read Evaluate Print Loop)工具,从命令行运行。
它是一个交互式Java Shell工具,它允许我们从shell执行Java代码并立即显示输出。

流程 API 改进( Process API)
J
ava 在 Java 9 版本中改进了它的进程 API,他们增加了几个新的类和方法来简化控制和管理。
在 Process API 有两个新接口:

  • java.lang.ProcessHandle
  • java.lang.ProcessHandle.Info

接口私有方法( Interface Private Methods)
在 Java 9 中,我们可以在接口内创建私有方法。接口允许我们声明 有助于在非抽象方法之间共享公共代码 的私有方法。

●Java 集合工厂方法(Java Collection Factory Methods)
集合工厂方法是特殊类型的静态方法,用于创建集合的不可修改实例。这意味着我们可以使用这些方法来创建少量元素的List、Set和Map。
它是不可修改的,所以添加新元素会抛出java.lang.UnsupportedOperation Exception

流 API 改进(Stream API)
Streams API 可以说是很长一段时间以来对 Java 标准库的最佳改进之一。
在Java 9中,Stream API得到了改进,并且在Stream接口中添加了新的4种方法:iterate(可以重载 迭代 器),dropWhile(从头开始删除,遇到不满足的就结束了),takeWhile(从头开始筛选,遇到不满足的就结束了),ofNullable(创建支持全 null 的 Stream)。

反应式流(Reactive Streams)
Java SE 9 反应式流 API 是一个发布/订阅框架,用于实现异步、可扩展和并行应用程序。
反应式流是关于流的异步处理 ,因此应该有一个发布服务器和一个订阅服务器。发布服务器发布数据流,订阅服务器使用数据。

HTTP 2 客户端(HTTP 2 Client)
Java 9 带来了执行 HTTP 调用的新方法。这个姗姗来迟的旧的HttpURLConnection API的替代品也支持WebSockets和HTTP/2协议。它支持同步(阻塞模式)和异步模式,使用上更加便利了。

G1 垃圾回收器(G1 Garbage Collector)
“Garbage-first”垃圾回收器,又名 G1,是一个并发多线程 GC。它主要与应用程序线程一起工作(很像并发标记扫描 GC),
旨在提供更短、更可预测的暂停时间 ,同时仍能实现高吞吐量。

其他新特性

  • Stack-Walking API( 提供一个标准API用于访问当前线程栈
  • Filter Incoming Serialization Data(通过过滤传入的序列化数据防止反序列化漏洞)
  • Deprecate the Applet API(弃用目前基本已不再使用的Applet小程序API)
  • Indify String Concatenation( 将 生成的静态串联字节码序列更改为使用对 JDK 库函数的调用,将支持将来对串联进行优化
  • Enhanced Method Handles(对Method Handles的增强)
  • Java Platform Logging API and Service( 一种通用机制来处理所有平台日志,并公开可由库和应用程序自定义的服务接口
  • Compact Strings(紧凑字符串,尽量使用 ISO-8859-1 /Latin-1编码存储 字符串 ,而不是 UTF-16
  • Parser API for Nashorn(JavaScript引擎升级)
  • Javadoc Search(支持在Javadoc进行搜索)
  • HTML5 Javadoc( 可输出兼容 HTML5 标准的J avadoc)

Java 10 最重要的特性和示例

Java 10是其23年历史中最快的Java版本。Java因其缓慢的增长和演变而受到批评,但Java 10打破了这个观念。

局部变量类型推理(Local- var iable Type Inference)
局部变量 类型推理是 Java 10 中面向开发人员的最大新特性。
与Javascript, Kotlin Scala 类似,现在Java也将有一个var关键字,允许您声明局部变量而无需指定其类型。

基于时间的发布版本控制(Time-Based Release Versioning)
从 JDK 10 版本开始,Java 采用了每六个月发布一次新版本的新时间表。有很多争论是否是一种实用的方法,大公司其实也欣赏Java迄今为止的稳定性和低变化率。

Oracle 已经对这些担忧做出了回应,并继续定期提供长期发布,但也以更长的时间间隔提供。而在Java 8之后,Java 11将再次得到长期支持。

事实上,Java 9和Java 10的支持刚刚结束,因为Java 11已经发布。

应用程序类数据共享(Application Class-Data Sharing)
此功能扩展了现有的 CDS 功能,允许将应用程序类放置在共享存档中,以改善启动和占用空间。

一般的想法是,当JVM首次启动时,加载的任何内容都会被序列化并存储在磁盘上的文件中,该文件可以在将来启动JVM时重新加载。

这意味着JVM的多个实例共享类元数据,因此不必每次都加载它们。

G1垃圾回收器的并行Full GC(Parallel Full GC for G1)

早在 Java 9 时就已经引入了 G1 垃圾收集器,G1 的优点很多,而在 Java 10 中还是做了小小调整,当 G1 的并发收集线程不能快速地完成Full GC 时,就会自动切换到并行收集,这可以减少在最坏情况下的 GC 时间。

垃圾回收器接口(Garbage-Collector Interface)
这是一个更有趣和有用的 Java 10 功能,它通过引入通用垃圾回收器接口来改进不同垃圾回收器的代码隔离。

它将有助于将来在不更改现有代码库的情况下添加新的GC,也有助于删除或收拾以前的GC。

根证书(Root Certificates)
在Java 10中,Oracle开源了Oracle的 Java SE Root CA程序中的根证书,以使OpenJDK构建对开发人员更具吸引力,并减少这些构建与Oracle JDK构建之间的差异。

线程本地握手(Thread-Local Handshakes)
这是一项内部 JVM 特性,用于提高性能。
此特性提供了一种在不执行全局 VM 安全点的情况下对线程执行 回调 的方法。使停止单个线程成为可能且成本低廉,而不仅仅是所有线程或无线程。

丰富API(API’s Added)
-为 List、Map & Set 等接口 添加了静态的 copy Of(Collection) 方法。它返回包含所提供条目的不可修改List、Map或Set。对于List,如果随后修改了给定的List,则返回的List将不会反映此类修改。

-Optional 及其原始变体添加了名为 orElseThrow()的方法。这和 get()方法完全相同,但是java文档指出它是 get() 的首选替代方案。

-Collectors 类获取用于收集不可修改集合(Set、List、Map)的各种方法。

Unicode 语言标签扩展

实现了最新的 LDML 规范 (opens new window)中指定的更多的扩展,如本地货币名称、本地语言名称等。

Java 11 最重要的特性和示例

Java 11 是继 Java 8 之后的第二个 LTS 版本。 从Java 11开始,Oracle JDK将不再免费用于商业用途。

运行 Java 文件(Running Java File
利用这个特性,我们可以避免编译阶段。我们可以在一个命令中编译并执行,我们使用 java 命令,它将隐式编译而不保存. class文件

Java 字符串方法(Java String Methods)
1) isBlank():如果字符串为空或仅包含空格代码点,则此方法返回 true。

2) lines() :返回字符串流的引用,这些字符串是我们在按行拆分后收到的子字符串。

3) strip()、stripLeading() 和 stripTrailing :删除字符串开头、结尾中的空白字符,支持Unicode空白字符。这是 trim () 的”Unicode-Aware”演变;

4) repeat():方法重复给定字符串指定次数。

在 Lambda 表达式中使用 var(Using var in Lambda Expressions)
从 Java 11 开始,我们可以在 lambda 表达式中使用 var 关键字。

在 lambda 表达式中使用 var 时,我们必须在所有参数上使用它,并且不能将其与使用特定类型混合使用。

基于嵌套的访问控制(Nested Based Access Control
在 Java 11 之前,Java 允许类和接口相互嵌套。这些嵌套类型彼此之间具有不受限制的访问权限,包括对私有字段、方法和构造函数的访问。

从 Java 11 开始, Class 类 中有一些新方法可以帮助我们获取有关所创建嵌套的信息。这些方法包括以下内容:
getNestHost() :返回此类对象所属的嵌套宿主

getNestMembers() :这返回一个数组,该数组包含一个数组,该类对象表示此类对象所属的嵌套的所有成员

isNestemateOf() : 确定给定的类是否是此类对象的嵌套对象

Epsilon:一个 No-Op 垃圾回收器(Epsilon: A No-Op Garbage Collector)
从 Java 11 开始,JVM 有一个实验性功能,允许我们在没有任何实际内存回收的情况下运行 JVM。

目标是提供具有有限分配限制和尽可能低延迟开销的完全被动垃圾回收器实现。

ZGC 可扩展低延迟 GC(ZGC Scalable Low Latency GC)
从 Java 11 开始,我们可以使用 ZGC。此新 GC 可作为实验性功能提供。
ZGC 是一个可扩展的低延迟垃圾回收器,它同时执行代价高昂的工作,而不会停止应用程序线程的执行超过 10 毫秒。

HTTP 客户端(HTTP Client)
从 Java 11 开始,HTTP 客户端 API 更加标准化。新的 API 同时支持 HTTP/1.1 和 HTTP/2,新的API还支持HTML5 WebSockets。

文件读取和写入(Files Reading and Writing)
Java 11 引入了
readString() writeString() 两种新方法,它们有助于从文件读取和写入字符串:

飞行记录器 (Flight Recorder)
飞行记录器 以前是Oracle JDK中的商业附加组件,现在是开源的,因为Oracle JDK本身不再是免费的。

JFR 是一个分析工具,用于从正在运行的 Java 应用程序收集诊断和分析数据。

它的性能开销可以忽略不计,通常低于1%。因此,它可用于生产应用。

Java 12 最重要的特性和示例

Java 12于2019年3月19日推出,这是六个月发布周期的一部分。
它是非 LTS 版本。因此,它不会有长期的支持。

● JVM 更改
Shenandoah 一个低暂停时间垃圾回收器:Java 12 添加了 Shenandoah(一种实验性的垃圾回收算法),通过在运行 Java 线程的同时执行疏散工作来减少垃圾回收暂停时间。

提示返回未使用的已提交内存 :G1 在空闲时自动将 Java 堆内存返回到操作系统。此内存在应用程序活动非常低的合理时间段内释放。

G1 的可中止混合集合 :G1 效率的提高包括,如果 G1 混合集合可能超过定义的暂停目标,则使 G1 混合集合可中止。这是通过将混合收集组拆分为必需收集组和可选收集组来完成的。

默认 CDS 存档 :目标是通过生成类数据共享 (CDS,class data-sharing) 存档来改进 JDK 构建过程。此功能的目标包括:
1)缩短开箱即用的启动时间。
2)不再需要-Xshare参数:转储以从CDS中受益。

Switch 表达式(预览)
使用此 JEP 在 Java 中 switch 有两个主要更改:
1) 引入case L -> 语法,不再需要 break 语句,因为只执行 -> 右边的语句。
2)switch可以是一个表达式,所以它可以是一个值,也可以作为一个返回值。

File.mismatch 方法
Java 12 添加了以下方法来比较两个文件:

如果内容一致,会返回 -1 ,如果内容不同,会返回不同的字节开始位置。

紧凑型数字格式(Compact Number Formatting)
Java 12 扩展了现有的数字格式化 API,以支持区分区域设置的紧凑数字格式。
现在,像1000(例如)这样的数字可以格式化为”1K”(短样式)或”1 thousand”(长样式)。

T形收集器(Teeing Collectors)
Teeing Collectors是 Streams API 中引入的新集合实用工具类。
此集合工具方法有三个参数:两个收集器和一个 Bi 函数。
所有输入值都会传递给两个收集器,其计算结果再一起传递给 Bi 函数进行合并,整体过程类似一个“T”形的三通件。

Java 字符串新方法

1) java.lang .String :

indent(int n) :根据 n 的值调整此字符串每行的缩进,并规范化行终止字符。

-如果 n > 0,则在每行的开头插入 n 个空格 (U+0020)。
-如果 n < 0,则从每行的开头删除
最多 n 个 空格字符。如果给定行不包含足够的空格,则删除所有前导空格字符。 制表符 也被视为单个字符。
-如果 n = 0,则该行保持不变。但是,行 终止符 会被规范化处理。

R transform(Function<? super String,​? extends R> f) : 此方法允许将传入的函数应用于当前字符串。

2) JVM Constants API :

常量 API 方法对于正常的开发相关任务没有太多用处。

Optional describeConstable() : 返回包含此实例的 Optional。

String resolveConstantDesc(MethodHandles.Lookup lookup) : 将此实例解析为 ConstantDesc,其结果是实例本身。

Java 13 最重要的特性和示例

Java 13 于 2019 年 9 月 17 日发布供生产使用。Java 13 中没有很多特定于开发人员的功能,因为发布周期为 6 个月。

switch 表达式(二次预览)
我们最初在 JDK 12 中看到switch表达式。Java 13 的 switch 表达式通过yield语句来支持传统的case:标签方式(不是->方式),同时用于封闭语句块(类似break),以返回一个值。

文本块(Text Blocks)(预览)
我们经常会处理包含多行字符串的文本块,例如嵌入式 JSON 、XML、 HTML 等。Java 13 文本块语法特性允许我们能够轻松创建多行字符串。多行字符串必须写在一对连续3个 双引号 之内。

早些时候,为了在代码中嵌入 JSON,我们会将其声明为字符串文本:

现在,它在我们的Java程序中轻松创建HTML和JSON字符串,很有用:

此外,java.lang.String现在有3种新方法来操作文本块:
1)formatted(Object… args):它类似于 String format() 方法。添加它以支持使用文本块进行格式设置。

2)stripIndent(): 用于从文本块中每行的开头和结尾删除附带的空格字符。此方法由文本块使用,并保留内容的相对缩进。

3)translateEscapes(): 返回一个值为当前字符串的字符串,但其中的转义字符会被转义。

●动态 CDS 存档(Dynamic CDS Archive)
类数据共享 (CDS) 一段时间以来一直是 Java HotSpot VM 的一个突出功能,它允许在不同的 JVM 之间共享类元数据,以减少启动时间和内存占用。
现在,创建CDS存档并使用它要容易得多。

ZGC:未使用的内存(Uncommit Unused Memory)(预览)
ZGC垃圾回收器是在 Java 11 中作为低延迟垃圾回收机制引入的,它会在堆内存清理之前添加一个较短的暂停时间。但是,未使用的内存并没有返还操作系统。

从 Java 13 开始,ZGC 现在缺省情况下将未提交的内存返回给操作系统。

FileSystems.newFileSystem() 方法
FileSystems 类中添加了三个新方法,
以便更容易地使用将文件内容视为文件系统的文件系统提供程序
-newFileSystem(Path)
-newFileSystem(Path, Map)
-newFileSystem(Path, Map, ClassLoader)

支持命名空间的 DOM 和 SAX 工厂
有新的方法可以实例化具有命名空间支持的 DOM 和 SAX 工厂:
-newDefaultNSInstance()
-newNSInstance()
-newNSInstance(String factoryClassName, ClassLoader classLoader)

杂项更改
Java 13 为我们提供了一些更显著的更改:
-java.time – 添加了新的日本官方时代名称

-javax.crypto – 支持 MS Cryptography Next Generation (CNG)
-javax.security – 添加属性 jdk.sasl.disabledMechanisms 以禁用 SASL 机制
-javax.xml.crypto – 引入了新的字符串常量来表示 Canonical XML 1.1 URI
-javax.xml.parsers – 添加了新方法,用于实例化具有命名空间支持的DOM 和 SAX 工厂

-Unicode 支持升级到版本 12.1
重新实现 Socket API
添加了对 Kerberos 主体名称规范化和跨领域引用的支持

Java 14 最重要的特性和示例

为了保持六个月的周期传统,Java 14是另一个非LTS版本,计划于2020年3月17日发布。

switch 表达式
switch 表达式 在前两个版本(Java 12、Java 13)中保持预览功能后,终于在 Java 14 中获得了永久地位。

● i nstanceof的模式匹配(Pattern Matching for instanceof)(预览)
将一个类型转换为另一个类型的旧方法是:

新的方式是:

在上面的代码中,仅当 obj 类型为 Journaldev 时,才会分配实例 jd,这种变量的作用域仅限于条件块。

有用的 NullPointerExceptions
改进了 JVM 生成的 NullPointerExceptions 异常消息。

在 Java 14 之前:

Java 14引入了一个新的JVM特性,它通过更具描述性的堆栈让问题一目了然,如下所示:

记录(Records)(预览)
我们需要编写大量低价值、重复的代码来负责任地编写简单的数据载体类:构造函数、访问器、equals()、hashCode()、toString() 等。为了避免这种重复的代码,Java计划使用record。

Record是一种轻量级的class,可以看做是数据结构体,和scala中的case有点相似。Record和普通的类的区别就在于Record多了一个括号括起来的定义的字段。

在Java 14之前:

Java 14 之后:

此外,我们可以通过以下方式向record添加其他字段、方法和构造函数:

关于record,需要注意的几件重要事情:
-record既不能继承一个类,也不能由另一个类继承,是个final类。
-record支持多个构造函数。
-record允许修改访问器方法。
-record不能是抽象的。
-record不能继承任何其他类,也不能在主体内定义实例字段,实例字段只能在状态描述中定义。
-record中声明的字段是private和final的。
-record的正文允许静态字段和方法。

文本块(Text Blocks)(预览)
文本块在 Java 13 中作为预览功能引入,目的是允许轻松创建多行字符串文本。它有助于轻松创建 HTML 和 JSON 或 SQL 查询字符串。

在 Java 14 中,文本块仍处于预览状态,并添加了一些新功能:
-反斜杠,用于显示美观的多行字符串块。
-\s 用于考虑编译器默认忽略的尾随空格,它会保留它之前存在的所有空格。

外部内存访问 API(Foreign-Memory Access API)
Java 14 JDK 中将引入一个有效的 Java API,它使 Java 应用程序能够安全高效地访问存储在 Java 堆外部的外部内存。外部内存访问 API 引入了三个主要抽象:内存分段(MemorySegment)、内存地址(MemoryAddress)和内存布局(MemoryLayout)。

Java 15 最重要的特性和示例

Java 15(Java SE 15)及其Java Development Kit 15(JDK 15)开源已于2020年9月15日发布。

文本块(Text Blocks)

文本块在 Java 12 中引入,在 Java 13 中开始预览,在 Java 14第二次预览,而现在,在 Java 15 ,文本块是正式的功能特性了。

封闭类(Sealed Classes)(预览)
封闭类在 Kotlin 中已经存在了一段时间,Java 15 最终引入了此功能,以便更好地控制继承。
可以使用密封的修饰符
密封类

因此,上述代码意味着,只有在关键字 permits 之后定义的类才允许扩展Vehicle密封类。

每个允许的类都必须使用显式修饰符进行设置。它可以是final,也可以是sealed或非密封的:
-一个被允许的子类,被声明为fianl的子类不能进一步扩展。
-声明为sealed允许子类可以进一步扩展,但只能通过子类允许的类进行扩展。
-允许的子类可以声明为非密封的,可以由任何类进一步扩展。超类不能进一步限制此类层次结构中的子类。

隐藏类(Hidden Classes)
这个特性让开发者可以引入一个无法被其它地方发现和使用,且类的生命周期有限的类。这对运行时动态生成类的使用方式十分有利,可以减少内存占用。

虽然大多数开发人员不会从中找到直接的好处,但任何使用动态字节码或JVM语言的人都可能会发现它们很有用。

隐藏类的目标是允许运行时创建不可发现的类。

这种类通常具有较短的生命周期,因此,隐藏类被设计为在加载和卸载时都非常有效。

外部内存 API(Foreign Memory API)
外部内存访问已经是 Java 14 的一个孵化功能。在Java 15中,目标是继续其孵化状态,同时添加几个新功能:
-一个新的VarHandle API,用于定制内存访问var句柄
-支持使用Spliterator接口并行处理内存段 -增强了对映射内存段的支持
-能够操作和取消引用来自本机调用等内容的地址
在Java 15中,ZGC和Shenandoah都将不再是实验性的。两者都将是团队可以选择使用的受支持配置,而G1收集器将保持默认值。

Nashorn JavaScript 引擎
由于 ECMAScript 语言发展很快,维护 Nashorn JavaScript (在 Java 8 中引入)的成本过于高昂,在 Java 15 中被彻底删除。随着最近GraalVM和其他VM技术的引入,很明显Nashorn在JDK生态系统中不再占有一席之地。

禁用和废弃偏向锁(Biased Locking)

当初使用偏向锁是为了提高性能,如今看来性能提升的程度和使用次数都不太有用。而偏向锁的引入增加了 JVM 的复杂性。所以,现在偏向锁被默认禁用,在不久的将来将会彻底删除,对于 Java 15,我们仍然可以使用-XX:+UseBiasedLocking 启用偏向锁定,但它会提示 这是一个已弃用的 API。

ZGC: 可扩展低延迟垃圾收集器

ZGC 垃圾收集器在 Java 11 中被引入,但是因为收集器的复杂性,当初决定逐渐引入,然后不断地听取用户的反馈建议修复问题。而现在,已经很久没有收到用户的问题反馈了,ZGC 是时候投入正式使用阶段了。

Shenandoah: 低停顿时间的垃圾收集器

Shenandoah 是一个高性能、低暂停时间的垃圾收集器,它是 Red Hat 主导的项目,在 Java 12 中开始引入,Java 15 中成为了正式功能的一部分,可使用-XX:+UseShenandoahGC启用。

Java 16 最重要的特性和示例

Java 16(Java SE 16)及其Java Development Kit 16(JDK 16)开源已于2021年3月16日发布,也不是长期支持版本。

伴随着数千个性能、稳定性和安全性更新,Java 16 为用户提供了十七项主要的增强 / 更改,包括三个孵化器模块和一个预览特性。

● i nstanceof的模式匹配( Pattern Matching for instanceof)

该特性在 JDK 14 中首次成为预览特性,在 JDK 16 中正式转正。

模式匹配的到来将使得 instanceof 变得更简洁、更安全,代码示例见前文。

记录(Records)

Records 在 JDK 14 中首次成为预览特性,在 JDK 16 中正式转正。代码示例见前文。

封闭类(Sealed Classes)(预览中)

可以是封闭类和或者封闭接口,用来增强 Java 编程语言,防止其他类或接口扩展或实现它们,在本版本仍然在预览中,用法见前文。

打包工具(Packaging Tool)

提供了 jpackage 打包工具,可用于打包独立的 Java 应用程序。

jpackage 打包工具是在 JDK 14 中首次作为孵化工具引入的新特性,到了 JDK 15 它仍然还在孵化中,现在它终于转正了。

弹性的元空间 (Elastic Metaspace)

弹性的Metaspace,可以帮助 HotSpot 虚拟机,将Metaspace中未使用的 class 元数据内存更及时地返回给操作系统,以减少元空间的内存占用空间。

另外,还简化了元空间的代码,以降低维护成本。

● ZGC并发栈处理( ZGC: Concurrent Thread-Stack Processing)

ZGC 是一种较新的垃圾回收器,指在解决 HotSpot 虚拟机中的 GC 停顿及可伸缩问题。

ZGC 最早是在 JDK 11 中集成进来的,在 JDK 15 中正式转正。

JDK16的这个版本则是为了让 ZGC 支持并发栈处理,解决了最后一个重大瓶颈,把 ZGC 中的线程栈处理从安全点(JVM 需要为每个线程选择一个点停止运行,这个点就叫做安全点)移到了并发阶段。并且还提供了一种机制,使得其他 HotSpot 子系统可以通过该机制延迟处理线程栈。

● 其它改进

-UNIX 域套接字通道(UNIX-Domain Socket Channels): 为 java.nio.channels 包中的套接字通道和服务端套接字通道 APIs 增加 Unix 域套接字通道所有特性支持。

JDK 内部默认强封装( Strongly Encapsulate JDK Internals by Default): JDK 16 开始对 JDK 内部大部分元素默认进行强封装,从而限制对它们的访问。用户仍然可以选择自 JDK 9 以来的默认的宽松的强封装。该特性目的是阻止第三方库、框架和工具使用 JDK 的内部 API 和包,增加了安全性。

-基于值的类的警告(Warnings for Value-Based Classes): 将基础类型包装类(如Integer、Long等)指定为基于值的类,废除其构造函数以进行删除,从而提示新的弃用警告。同时还提供了在任何基于值的类的实例上不正常进行同步的警告。

-Vector API (孵化): 用于表示在运行时可靠地编译到支持的 CPU 架构上的最佳矢量硬件指令的矢量计算。

-Foreign Linker API (孵化): 提供了对本地 native 代码的静态类型访问支持,替换了之前的 JNI 形式。

-Foreign-Memory Access API (第三次孵化): 可以帮助 Java 应用程序更安全、有效地访问 Java 堆之外的外部内存,自JDK14开始,仍然在孵化中。

Enable C++14 Language Features (in the JDK source code): 允许 在 JDK 的 C++ 源码中使用 C++ 14 的语言特性,并且给出了哪些特性可以在 HotSpot 代码中使用的具体说明。该特性与Java开发人员关系不大。

Migrate from Mercurial to Git: 将 OpenJDK 社区的源代码存储库从 Mercurial(hg)迁移到 Git。

Migrate to GitHub: 在 GitHub 上托管 OpenJDK 社区的 Git 存储库。只对 JDK 11 以及更高版本 JDK 进行了迁移。

Alpine Linux Port: Apine Linux 是一个独立的、非商业的 Linux 发行版,它十分的小,并且十分的简单,同时兼顾了安全性。在 x64 和 AArch64 平台体系结构上,将 JDK 移植到 Alpine Linux 以及使用 musl 作为其主要 C 语言库的其他 Linux 发行版中。

Windows/Aarch64 Port: Windows/AArch64 已经是终端用户市场的热门需求,本特性将 JDK 移植到 Windows/ AArch64 平台系列。

Java 17 最重要的特性和示例

Java 17 是一个长期支持版本(到2030年),发布于2021年9月。

Java 新特性的设计者说过,如果你从JDK 8 迁移到 JDK 17,再搭配上 JDK 8 以后的新技术,产品的代码量至少可以减少20%,代码错误至少可以减少20%,相应的产品性能可以提高20%,维护成本也可以降低20%。

封闭类(Sealed Classes)

封闭类可以限制哪些其他类可以扩展它们,在Java 17中正式发布了这个特性。

switch 的类型模式匹配(预览中)

如 instanceof 一样,为 switch 也增加了类型匹配自动转换功能。

● 其它改进

-恢复始终严格的浮点语义: 在硬件性能大幅提升的今天,将始终进行严格浮点运算,而不必再使用strictfp关键字

增强的伪随机数生成器: 为伪随机数生成器 RPNG(pseudorandom number generator)增加了新的接口类型和实现,让在代码中使用各种 PRNG 算法变得容易许多。

-使用新的 macOS 渲染库: 支持 Apple Metal图形渲染库,不过对于 API 没有任何改变,这一些都是内部修改。

-支持 macOS/AArch64 架构: Apple将开启一项长期的将 Macintosh 计算机系列从 x64 过度到 AArch64 的长期计划,因此需要尽快的让 JDK 支持 macOS/AArch64 。

-删除已弃用的 Applet API: Applet(可以嵌入到 HTML 中的小应用程序) API 在 Java 9 时已经标记了废弃,现在 Java 17 中将彻底删除。

-更强的 JDK 内部封装: 此更改,JDK 的内部包和 API(关键内部 API (opens new window)除外)将不再默认打开。使用 –illegal-access 选项将会得到一个命令已经移除的警告。

-移除 RMI Activation: RMI Activation 在 Java 15 中已经被标记为过时废弃,至今没有收到不良反馈,因此决定在 Java 17 中正式移除。RMI 其他部分不会受影响。

-移除实验性的 AOT 和 JIT 编译器: 在 Java 9 引入了实验性的提前编译 jaotc 工具,但是这个特性自从引入以来用处都不太大,而且需要大量的维护工作,所以在 Java 17 中决定删除这个特性。

-弃用 Security Manager: Security Manager 在 JDK 1.0 时就已经引入,但是一直用处不大,为了 Java 的继续发展,决定弃用 Security Manager,在不久的未来进行删除。

-外部函数和内存 API(孵化中): 允许 Java 开发者在不使用 JNDI 的情况下与 JVM 之外的代码和数据进行交互。

-Vector API(继续孵化): 改进了Java 16 开始孵化的 Vector API 的性能,增强了例如对字符的操作、字节向量与布尔数组之间的相互转换等功能。

-指定上下文的反序列化过滤器: 允许在反序列化时,通过一个过滤配置,来告知本次反序列化允许或者禁止操作的类,反序列化时碰到被禁止的类,则会反序列化失败。

结论

本文介绍了Java从Java 8到Java 17的演变。

自六年前Java 8发布以来,Java作为一种语言和一个生态系统已经发生了巨大的变化,它增加了许多新功能,与其他基于JVM的竞争对手相比,Java成为一种有竞争力的选择。


这是一个查看Java各版本特性较好的网站,强烈推荐:

这篇文章也不错,作者用心了:

文章来源:智云一二三科技

文章标题:Java在过去7年的发展(从Java 8到Java 17)

文章地址:https://www.zhihuclub.com/182853.shtml

关于作者: 智云科技

热门文章

网站地图