From 814780f7390af74864cf6b39d78e967157c19bc7 Mon Sep 17 00:00:00 2001 From: guide Date: Mon, 16 Aug 2021 16:42:31 +0800 Subject: [PATCH] =?UTF-8?q?[feat]java10,11=20=E6=96=B0=E7=89=B9=E6=80=A7?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...带你看遍JDK9到14的重要新特性.md | 152 +++++++++++++----- 1 file changed, 113 insertions(+), 39 deletions(-) diff --git a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md index dc1d4318..4354d219 100644 --- a/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md +++ b/docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md @@ -38,8 +38,8 @@ Java 9 模块的重要特征是在其工件(artifact)的根目录中包含 想要深入了解 Java 9 的模块化,参见: -- [Project Jigsaw: Module System Quick-Start Guide](https://openjdk.java.net/projects/jigsaw/quick-start) -- [Java 9 Modules: part 1](https://stacktraceguru.com/java9/module-introduction) +- [《Project Jigsaw: Module System Quick-Start Guide》](https://openjdk.java.net/projects/jigsaw/quick-start) +- [《Java 9 Modules: part 1》](https://stacktraceguru.com/java9/module-introduction) ### Jshell @@ -59,6 +59,8 @@ Set.of("Java", "C++"); Map.of("Java", 1, "C++", 2)`; ``` +使用 `of()` 创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 `java.lang.UnsupportedOperationException` 异常。 + `Collectors` 中增加了新的方法 `filtering()` 和 `flatMapping()`。 `Collectors` 的 `filtering()` 方法类似于 `Stream` 类的 `filter()` 方法,都是用于过滤元素。 @@ -165,8 +167,9 @@ Java 9 允许为 JDK 和应用配置同样的日志实现。新增了 `System.Lo ### 反应式流 ( Reactive Streams ) -- 在 Java9 中的 `java.util.concurrent.Flow` 类中新增了反应式流规范的核心接口 -- Flow 中包含了 `Flow.Publisher`、`Flow.Subscriber`、`Flow.Subscription` 和 `Flow.Processor` 等 4 个核心接口。Java 9 还提供了`SubmissionPublisher` 作为`Flow.Publisher` 的一个实现。 +在 Java9 中的 `java.util.concurrent.Flow` 类中新增了反应式流规范的核心接口 。 + +`Flow` 中包含了 `Flow.Publisher`、`Flow.Subscriber`、`Flow.Subscription` 和 `Flow.Processor` 等 4 个核心接口。Java 9 还提供了`SubmissionPublisher` 作为`Flow.Publisher` 的一个实现。 ### 变量句柄 @@ -192,9 +195,9 @@ public interface MyInterface { } ``` -### 其它新特性 +### Java9 其它新特性 -- **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章 [https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html](https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html)) +- **try-with-resources 增强** :在 try-with-resources 语句中可以使用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章:[《Effectively Final Variables in Java》](https://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html) - 类 `CompletableFuture` 中增加了几个新的方法(`completeAsync` ,`orTimeout` 等) - **Nashorn 引擎的增强** :Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些增强,实现了一些 ES6 的新特性(Java 11 中已经被弃用)。 - **I/O 流的新特性** :增加了新的方法来读取和复制 `InputStream` 中包含的数据 @@ -205,16 +208,45 @@ public interface MyInterface { 发布于 2018 年 3 月 20 日,最知名的特性应该是 var 关键字(局部变量类型推断)的引入了,其他还有垃圾收集器改善、GC 改进、性能提升、线程管控等一批新特性 -### var 关键字 +### var(局部变量推断) -- **介绍** :提供了 var 关键字声明局部变量:`var list = new ArrayList(); // ArrayList` -- **局限性** :只能用于带有构造器的**局部变量**和 for 循环中 +由于太多 Java 开发者希望 Java 中引入局部变量推断,于是 Java 10 的时候它来了,也算是众望所归了! -_Guide 哥:实际上 Lombok 早就体用了一个类似的关键字,使用它可以简化代码,但是可能会降低程序的易读性、可维护性。一般情况下,我个人都不太推荐使用。_ +Java 10 提供了 var 关键字声明局部变量。 -### 不可变集合 +> Scala 和 Kotlin 中有 val 关键字 ( `final var` 组合关键字),Java10 中并没有引入。 -**list,set,map 提供了静态方法`copyOf()`返回入参集合的一个不可变拷贝(以下为 JDK 的源码)** +Java 10 只引入了 var,而 + +```java +var id = 0; +var codefx = new URL("https://mp.weixin.qq.com/"); +var list = new ArrayList<>(); +var list = List.of(1, 2, 3); +var map = new HashMap(); +var p = Paths.of("src/test/java/Java9FeaturesTest.java"); +var numbers = List.of("a", "b", "c"); +for (var n : list) + System.out.print(n+ " "); +``` + +var 关键字只能用于带有构造器的局部变量和 for 循环中。 + +```java +var count=null; //❌编译不通过,不能声明为 null +var r = () -> Math.random();//❌编译不通过,不能声明为 Lambda表达式 +var array = {1,2,3};//❌编译不通过,不能声明数组 +``` + +var 并不会改变 Java 是一门静态类型语言的事实,编译器负责推断出类型。 + +相关阅读:[《Java 10 新特性之局部变量类型推断》](https://zhuanlan.zhihu.com/p/34911982)。 + +### 集合增强 + +`list`,`set`,`map` 提供了静态方法`copyOf()`返回入参集合的一个不可变拷贝。 + +以下为 JDK 的源码: ```java static List copyOf(Collection coll) { @@ -222,11 +254,26 @@ static List copyOf(Collection coll) { } ``` -**`java.util.stream.Collectors`中新增了静态方法,用于将流中的元素收集为不可变的集合** +使用 `copyOf()` 创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 `java.lang.UnsupportedOperationException` 异常。 IDEA 也会有相应的提示。 + +![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/image-20210816154125579.png) + +`java.util.stream.Collectors` 中新增了静态方法,用于将流中的元素收集为不可变的集合。 + +```java +var list = new ArrayList<>(); +list.stream().collect(Collectors.toUnmodifiableList()); +list.stream().collect(Collectors.toUnmodifiableSet()); +``` ### Optional -- 新增了`orElseThrow()`方法来在没有值时抛出异常 +新增了`orElseThrow()`方法来在没有值时抛出指定的异常。 + +```java +Optional.ofNullable(cache.getIfPresent(key)) + .orElseThrow(() -> new PrestoException(NOT_FOUND, "Missing entry found for key: " + key)); +``` ### 并行全垃圾回收器 G1 @@ -240,12 +287,12 @@ static List copyOf(Collection coll) { Java 10 在现有的 CDS 功能基础上再次拓展,以允许应用类放置在共享存档中。CDS 特性在原来的 bootstrap 类基础之上,扩展加入了应用类的 CDS (Application Class-Data Sharing) 支持。其原理为:在启动时记录加载类的过程,写入到文本文件中,再次启动时直接读取此启动文本并加载。设想如果应用环境没有大的变化,启动速度就会得到提升 -### 其他特性 +### Java10 其他新特性 - **线程-局部管控**:Java 10 中线程管控引入 JVM 安全点的概念,将允许在不运行全局 JVM 安全点的情况下实现线程回调,由线程本身或者 JVM 线程来执行,同时保持线程处于阻塞状态,这种方式使得停止单个线程变成可能,而不是只能启用或停止所有线程 - - **备用存储装置上的堆分配**:Java 10 中将使得 JVM 能够使用适用于不同类型的存储机制的堆,在可选内存设备上进行堆内存分配 - **统一的垃圾回收接口**:Java 10 中,hotspot/gc 代码实现方面,引入一个干净的 GC 接口,改进不同 GC 源代码的隔离性,多个 GC 之间共享的实现细节代码应该存在于辅助类中。统一垃圾回收接口的主要原因是:让垃圾回收器(GC)这部分代码更加整洁,便于新人上手开发,便于后续排查相关问题。 +- ...... ## Java11 @@ -253,11 +300,11 @@ Java11 于 2018 年 9 月 25 日正式发布,这是很重要的一个版本! ![](https://img-blog.csdnimg.cn/20210603202746605.png) -### 字符串加强 +### String Java 11 增加了一系列的字符串处理方法,如以下所示。 -_Guide 哥:说白点就是多了层封装,JDK 开发组的人没少看市面上常见的工具类框架啊!_ +_Guide:说白点就是多了层封装,JDK 开发组的人没少看市面上常见的工具类框架啊!_ ```java //判断字符串是否为空 @@ -276,6 +323,15 @@ _Guide 哥:说白点就是多了层封装,JDK 开发组的人没少看市面 "A\nB\nC".lines().collect(Collectors.toList()); ``` +### Optional + +新增了`empty()`方法来判断指定的 `Optional` 对象是否为空。 + +```java +var op = Optional.empty(); +System.out.println(op.isEmpty());//判断指定的 Optional 对象是否为空 +``` + ### ZGC:可伸缩低延迟垃圾收集器 **ZGC 即 Z Garbage Collector**,是一个可伸缩的、低延迟的垃圾收集器。 @@ -289,15 +345,19 @@ ZGC 主要为了满足如下目标进行设计: - 针以及 Load barriers 优化奠定基础 - 当前只支持 Linux/x64 位平台 -ZGC 目前 **处在实验阶段**,只支持 Linux/x64 平台 +ZGC 目前 **处在实验阶段**,只支持 Linux/x64 平台。 + +与 CMS 中的 ParNew 和 G1 类似,ZGC 也采用标记-复制算法,不过 ZGC 对该算法做了重大改进。 + +在 ZGC 中出现 Stop The World 的情况会更少! + +详情可以看 : [《新一代垃圾回收器 ZGC 的探索与实践》](https://tech.meituan.com/2020/08/06/new-zgc-practice-in-meituan.html) ### 标准 HTTP Client 升级 Java 11 对 Java 9 中引入并在 Java 10 中进行了更新的 Http Client API 进行了标准化,在前两个版本中进行孵化的同时,Http Client 几乎被完全重写,并且现在完全支持异步非阻塞。 -并且,Java11 中,Http Client 的包名由 `jdk.incubator.http` 改为`java.net.http`,该 API 通过 `CompleteableFuture` 提供非阻塞请求和响应语义。 - -使用起来也很简单,如下: +并且,Java11 中,Http Client 的包名由 `jdk.incubator.http` 改为`java.net.http`,该 API 通过 `CompleteableFuture` 提供非阻塞请求和响应语义。使用起来也很简单,如下: ```java var request = HttpRequest.newBuilder() @@ -316,28 +376,42 @@ client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenAccept(System.out::println); ``` -### 简化启动单个源代码文件的方法 +### var(Lambda 参数的局部变量语法) -- 增强了 Java 启动器,使其能够运行单一文件的 Java 源代码。此功能允许使用 Java 解释器直接执行 Java 源代码。源代码在内存中编译,然后由解释器执行。唯一的约束在于所有相关的类必须定义在同一个 Java 文件中 -- 对于 Java 初学者并希望尝试简单程序的人特别有用,并且能和 jshell 一起使用 -- 一定能程度上增强了使用 Java 来写脚本程序的能力 +从 Java 10 开始,便引入了局部变量类型推断这一关键特性。类型推断允许使用关键字 var 作为局部变量的类型而不是实际类型,编译器根据分配给变量的值推断出类型。 -### 用于 Lambda 参数的局部变量语法 +Java 10 中对 var 关键字存在几个限制 -- 从 Java 10 开始,便引入了局部变量类型推断这一关键特性。类型推断允许使用关键字 var 作为局部变量的类型而不是实际类型,编译器根据分配给变量的值推断出类型 -- Java 10 中对 var 关键字存在几个限制 - - 只能用于局部变量上 - - 声明时必须初始化 - - 不能用作方法参数 - - 不能在 Lambda 表达式中使用 -- Java11 开始允许开发者在 Lambda 表达式中使用 var 进行参数声明 +- 只能用于局部变量上 +- 声明时必须初始化 +- 不能用作方法参数 +- 不能在 Lambda 表达式中使用 -### 其他特性 +Java11 开始允许开发者在 Lambda 表达式中使用 var 进行参数声明。 -- 新的垃圾回收器 Epsilon,一个完全消极的 GC 实现,分配有限的内存资源,最大限度的降低内存占用和内存吞吐延迟时间 -- 低开销的 Heap Profiling:Java 11 中提供一种低开销的 Java 堆分配采样方法,能够得到堆分配的 Java 对象信息,并且能够通过 JVMTI 访问堆信息 -- TLS1.3 协议:Java 11 中包含了传输层安全性(TLS)1.3 规范(RFC 8446)的实现,替换了之前版本中包含的 TLS,包括 TLS 1.2,同时还改进了其他 TLS 功能,例如 OCSP 装订扩展(RFC 6066,RFC 6961),以及会话散列和扩展主密钥扩展(RFC 7627),在安全性和性能方面也做了很多提升 -- 飞行记录器:飞行记录器之前是商业版 JDK 的一项分析工具,但在 Java 11 中,其代码被包含到公开代码库中,这样所有人都能使用该功能了 +```java +// 下面两者是等价的 +Consumer consumer = (var i) -> System.out.println(i); +Consumer consumer = (String i) -> System.out.println(i); +``` + +### 启动单文件源代码程序 + +[JEP 330:启动单文件源代码程序(aunch Single-File Source-Code Programs)](https://openjdk.java.net/jeps/330) 可以让我们运行单一文件的 Java 源代码。此功能允许使用 Java 解释器直接执行 Java 源代码。源代码在内存中编译,然后由解释器执行,不需要在磁盘上生成 `.class` 文件了。 + +唯一的约束在于所有相关的类必须定义在同一个 Java 文件中。 + +对于 Java 初学者并希望尝试简单程序的人特别有用,并且能和 jshell 一起使用 + +一定能程度上增强了使用 Java 来写脚本程序的能力。 + +### Java11 其他新特性 + +- **新的垃圾回收器 Epsilon** :一个完全消极的 GC 实现,分配有限的内存资源,最大限度的降低内存占用和内存吞吐延迟时间 +- **低开销的 Heap Profiling** :Java 11 中提供一种低开销的 Java 堆分配采样方法,能够得到堆分配的 Java 对象信息,并且能够通过 JVMTI 访问堆信息 +- **TLS1.3 协议** :Java 11 中包含了传输层安全性(TLS)1.3 规范(RFC 8446)的实现,替换了之前版本中包含的 TLS,包括 TLS 1.2,同时还改进了其他 TLS 功能,例如 OCSP 装订扩展(RFC 6066,RFC 6961),以及会话散列和扩展主密钥扩展(RFC 7627),在安全性和性能方面也做了很多提升 +- **飞行记录器(Java Flight Recorder)** :飞行记录器之前是商业版 JDK 的一项分析工具,但在 Java 11 中,其代码被包含到公开代码库中,这样所有人都能使用该功能了。 +- ...... ## Java12