Java9
公布于 2017 年 9 月 21 日。作为 Java8 之后 3 年半才公布的新版本,Java 9 带 来了很多重大的变动其中最重要的改变是 Java 平台模块零碎的引入, 其余还有诸如汇合、Stream 流
Java 平台模块零碎
Java 平台模块零碎,也就是 Project Jigsaw,把模块化开发实际引入到了 Java 平台中。在引入了模块零碎之后,JDK 被从新组织成 94 个模块。Java 利用能够通过新增的 jlink 工具,创立出只蕴含所依赖的 JDK 模块的自定义运行时镜像。这样能够极大的缩小 Java 运行时环境的大小。
Java 9 模块的重要特色是在其工件(artifact)的根目录中蕴含了一个形容模块的 module-info.class 文 件。工件的格局能够是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。
Jshell
jshell 是 Java 9 新增的一个实用工具。为 Java 提供了相似于 Python 的实时命令行交互工具。
在 Jshell 中能够间接输出表达式并查看其执行后果
汇合、Stream 和 Optional
- 减少 了
List.of()
、Set.of()
、Map.of()
和Map.ofEntries()
等工厂办法来创立不可变汇合,比方List.of("Java", "C++");
、Map.of("Java", 1, "C++", 2)
;(这部分内容有点参考 Guava 的滋味) Stream
中减少了新的办法ofNullable
、dropWhile
、takeWhile
和iterate
办法。Collectors
中减少了新的办法filtering
和flatMapping
Optional
类中新增了ifPresentOrElse
、or
和stream
等办法
过程 API
Java 9 减少了 ProcessHandle
接口,能够对原生过程进行治理,尤其适宜于治理长时间运行的过程
平台日志 API 和服务
Java 9 容许为 JDK 和利用配置同样的日志实现。新增了 System.LoggerFinder
用来治理 JDK 使 用的日志记录器实现。JVM 在运行时只有一个零碎范畴的 LoggerFinder
实例。
咱们能够通过增加本人的 System.LoggerFinder
实现来让 JDK 和利用应用 SLF4J 等其余日志记录框架。
反应式流(Reactive Streams)
- 在 Java9 中的
java.util.concurrent.Flow
类中新增了反应式流标准的外围接口 - Flow 中蕴含了
Flow.Publisher
、Flow.Subscriber
、Flow.Subscription
和Flow.Processor
等 4 个外围接口。Java 9 还提供了SubmissionPublisher
作为Flow.Publisher
的一个实现。
变量句柄
- 变量句柄是一个变量或一组变量的援用,包含动态域,非动态域,数组元素和堆外数据结构中的组成部分等
- 变量句柄的含意相似于已有的办法句柄
MethodHandle
- 由 Java 类
java.lang.invoke.VarHandle
来示意,能够应用类java.lang.invoke.MethodHandles.Lookup
中的动态工厂办法来创立VarHandle
对 象
改良办法句柄(Method Handle)
- 办法句柄从 Java7 开始引入,Java9 在类
java.lang.invoke.MethodHandles
中新增了更多的静态方法来创立不同类型的办法句柄
其它新个性
- 接口公有办法:Java 9 容许在接口中应用公有办法
- try-with-resources 加强:在 try-with-resources 语句中能够应用 effectively-final 变量(什么是 effectively-final 变量,见这篇文章 http://ilkinulas.github.io/programming/java/2016/03/27/effectively-final-java.html)
- 类
CompletableFuture
中减少了几个新的办法(completeAsync
,orTimeout
等) - Nashorn 引擎的加强:Nashorn 从 Java8 开始引入的 JavaScript 引擎,Java9 对 Nashorn 做了些加强,实现了一些 ES6 的新个性
- I/O 流的新个性:减少了新的办法来读取和复制 InputStream 中蕴含的数据
- 改良利用的平安性能:Java 9 新增了 4 个 SHA- 3 哈希算法,SHA3-224、SHA3-256、SHA3-384 和 S HA3-512
- …
Java10
公布于 2018 年 3 月 20 日,最出名的个性应该是 var 关键字(局部变量类型推断)的引入了,其余还有垃圾收集器改善、GC 改良、性能晋升、线程管控等一批新个性
var 关键字
- 介绍 : 提供了 var 关键字申明局部变量:
var list = new ArrayList<String>(); // ArrayList<String>
- 局限性:只能用于带有结构器的局部变量和 for 循环中
Guide 哥:实际上 Lombok 早就体用了一个相似的关键字,应用它能够简化代码,然而可能会升高程序的易读性、可维护性。个别状况下,我集体都不太举荐应用。
不可变汇合
list,set,map 提供了静态方法 copyOf()
返回入参汇合的一个不可变拷贝(以下为 JDK 的源码)
static <E> List<E> copyOf(Collection<? extends E> coll) {return ImmutableCollections.listCopy(coll);
}
java.util.stream.Collectors
中新增了静态方法,用于将流中的元素收集为不可变的汇合
Optional
- 新增了
orElseThrow()
办法来在没有值时抛出异样
并行全垃圾回收器 G1
从 Java9 开始 G1 就了默认的垃圾回收器,G1 是以一种低延时的垃圾回收器来设计的,旨在防止进行 Full GC, 然而 Java9 的 G1 的 FullGC 仍然是应用单线程去实现标记革除算法, 这可能会导致垃圾回收期在无奈回收内存的时候触发 Full GC。
为了最大限度地缩小 Full GC 造成的利用进展的影响,从 Java10 开始,G1 的 FullGC 改为并行的标记革除算法,同时会应用与年老代回收和混合回收雷同的并行工作线程数量,从而缩小了 Full GC 的产生,以带来更好的性能晋升、更大的吞吐量。
应用程序类数据共享
在 Java 5 中就曾经引入了类数据共享机制 (Class Data Sharing,简称 CDS),容许将一组类预处理为共享归档文件,以便在运行时可能进行内存映射以缩小 Java 程序的启动工夫,当多个 Java 虚拟机(JVM)共享雷同的归档文件时,还能够缩小动态内存的占用量,同时缩小多个虚拟机在同一个物理或虚构的机器上运行时的资源占用
Java 10 在现有的 CDS 性能根底上再次拓展,以容许利用类搁置在共享存档中。CDS 个性在原来的 bootstrap 类根底之上,扩大退出了利用类的 CDS (Application Class-Data Sharing) 反对。其原理为:在启动时记录加载类的过程,写入到文本文件中,再次启动时间接读取此启动文本并加载。构想如果应用环境没有大的变动,启动速度就会失去晋升
其余个性
- 线程 - 部分管控:Java 10 中线程管控引入 JVM 平安点的概念,将容许在不运行全局 JVM 平安点的状况下实现线程回调,由线程自身或者 JVM 线程来执行,同时放弃线程处于阻塞状态,这种形式使得进行单个线程变成可能,而不是只能启用或进行所有线程
- 备用存储安装上的堆调配:Java 10 中将使得 JVM 可能应用实用于不同类型的存储机制的堆,在可选内存设施上进行堆内存调配
- 对立的垃圾回收接口:Java 10 中,hotspot/gc 代码实现方面,引入一个洁净的 GC 接口,改良不同 GC 源代码的隔离性,多个 GC 之间共享的实现细节代码应该存在于辅助类中。对立垃圾回收接口的次要起因是:让垃圾回收器(GC)这部分代码更加整洁,便于新人上手开发,便于后续排查相干问题。
Java11
Java11 于 2018 年 9 月 25 日正式公布,这是很重要的一个版本!Java 11 和 2017 年 9 月份公布的 Java 9 以及 2018 年 3 月份公布的 Java 10 相比,其最大的区别就是:在长期反对 (Long-Term-Support) 方面,Oracle 示意会对 Java 11 提供大力支持,这一反对将会继续至 2026 年 9 月。这是据 Java 8 当前反对的首个长期版本。
字符串增强
Java 11 减少了一系列的字符串解决办法,如以下所示。
Guide 哥:说白点就是多了层封装,JDK 开发组的人没少看市面上常见的工具类框架啊!
// 判断字符串是否为空
” “.isBlank();//true // 去除字符串首尾空格
” Java “.strip();// “Java” // 去除字符串首部空格
” Java “.stripLeading(); // “Java ” // 去除字符串尾部空格
” Java “.stripTrailing(); // ” Java” // 反复字符串多少次
“Java”.repeat(3); // “JavaJavaJava” // 返回由行终止符分隔的字符串汇合。
“AnBnC”.lines().count(); // 3
“AnBnC”.lines().collect(Collectors.toList());
ZGC:可伸缩低提早垃圾收集器
ZGC 即 Z Garbage Collector,是一个可伸缩的、低提早的垃圾收集器。
ZGC 次要为了满足如下指标进行设计:
- GC 进展工夫不超过 10ms
- 即能解决几百 MB 的小堆,也能解决几个 TB 的大堆
- 利用吞吐能力不会降落超过 15%(与 G1 回收算法相比)
- 不便在此基础上引入新的 GC 个性和利用 colord
- 针以及 Load barriers 优化奠定根底
- 以后只反对 Linux/x64 位平台
ZGC 目前 处在试验阶段,只反对 Linux/x64 平台
规范 HTTP Client 降级
Java 11 对 Java 9 中引入并在 Java 10 中进行了更新的 Http Client API 进行了标准化,在前两个版本中进行孵化的同时,Http Client 简直被齐全重写,并且当初齐全反对异步非阻塞。
并且,Java11 中,Http Client 的包名由 jdk.incubator.http
改为java.net.http
,该 API 通过 CompleteableFuture
提供非阻塞申请和响应语义。
应用起来也很简略,如下:
var request = HttpRequest.newBuilder()
.uri(URI.create("https://javastack.cn"))
.GET()
.build();
var client = HttpClient.newHttpClient(); // 同步
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body()); // 异步
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
简化启动单个源代码文件的办法
- 加强了 Java 启动器,使其可能运行繁多文件的 Java 源代码。此性能容许应用 Java 解释器间接执行 Java 源代码。源代码在内存中编译,而后由解释器执行。惟一的束缚在于所有相干的类必须定义在同一个 Java 文件中
- 对于 Java 初学者并心愿尝试简略程序的人特地有用,并且能和 jshell 一起应用
- 肯定能水平上加强了应用 Java 来写脚本程序的能力
用于 Lambda 参数的局部变量语法
- 从 Java 10 开始,便引入了局部变量类型推断这一要害个性。类型推断容许应用关键字 var 作为局部变量的类型而不是理论类型,编译器依据调配给变量的值推断出类型
-
Java 10 中对 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 中,其代码被蕴含到公开代码库中,这样所有人都能应用该性能了
Java12
加强 Switch
- 传统的 switch 语法存在容易漏写 break 的问题,而且从代码整洁性层面来看,多个 break 实质也是一种反复
- Java12 提供了 swtich 表达式,应用相似 lambda 语法条件匹配胜利后的执行块,不须要多写 break
- 作为预览个性退出,须要在
javac
编译和java
运行时减少参数--enable-preview
switch (day) {case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9);
}
数字格式化工具类
NumberFormat
新增了对简单的数字进行格式化的反对
NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
String result = fmt.format(1000);
System.out.println(result); // 输入为 1K,计算工资是多少 K 更不便了。。。
Shenandoah GC
- Redhat 主导开发的 Pauseless GC 实现,次要指标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等
- 和 Java11 开源的 ZGC 相比(须要降级到 JDK11 能力应用),Shenandoah GC 有稳固的 JDK8u 版本,在 Java8 占据次要市场份额的明天有更大的可落地性
G1 收集器晋升
-
Java12 为默认的垃圾收集器 G1 带来了两项更新:
- 可停止的混合收集汇合:JEP344 的实现,为了达到用户提供的进展工夫指标,JEP 344 通过把要被回收的区域集(混合收集汇合)拆分为强制和可选局部,使 G1 垃圾回收器能停止垃圾回收过程。G1 能够停止可选局部的回收以达到进展工夫指标
- 及时返回未应用的已分配内存:JEP346 的实现,加强 G1 GC,以便在闲暇时主动将 Java 堆内存返回给操作系统
Java13
引入 yield 关键字到 Switch 中
Switch
表达式中就多了一个关键字用于跳出Switch
块的关键字yield
,次要用于返回一个值-
yield
和return
的区别在于:return
会间接跳出以后循环或者办法,而yield
只会跳出以后Switch
块,同时在应用yield
时,须要有default
条件private static String descLanguage(String name) {return switch (name) {case “Java”: yield “object-oriented, platform independent and secured”; case “Ruby”: yield “a programmer’s best friend”; default: yield name +” is a good language”;
};
}
文本块
- 解决 Java 定义多行字符串时只能通过换行本义或者换行连接符来变通反对的问题,引入三重双引号来定义多行文本
-
两个
"""
两头的任何内容都会被解释为字符串的一部分,包含换行符String json =”{n” +
""name":"mkyong",n"+" "age":38n"+"}n"; // 未反对文本块之前
String json = “””
{“name”:”mkyong”, “age”:38} “””;
加强 ZGC 开释未应用内存
- 在 Java 11 中是实验性的引入的 ZGC 在理论的应用中存在未能被动将未应用的内存开释给操作系统的问题
- ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages 区域时,它们将被开释并返回到页面缓存 ZPageCache 中,此缓存中的 ZPages 按最近起码应用(LRU)的程序,并依照大小进行组织
- 在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未应用的页面,这样它们将能够被其余过程重用
SocketAPI 重构
- Java 13 为 Socket API 带来了新的底层实现办法,并且在 Java 13 中是默认应用新的 Socket 实现,使其易于发现并在排除问题同时减少可维护性
动静应用程序类 - 数据共享
- Java 13 中对 Java 10 中引入的 应用程序类数据共享进行了进一步的简化、改良和扩大,即:容许在 Java 应用程序执行完结时动静进行类归档,具体可能被归档的类包含:所有已被加载,但不属于默认基层 CDS 的应用程序类和援用类库中的类
Java14
record 关键字
- 简化数据类的定义形式,应用 record 代替 class 定义的类,只须要申明属性,就能够在取得属性的拜访办法,以及 toString,hashCode,equals 办法
- 相似于应用 Class 定义类,同时应用了 lomobok 插件,并打上了
@Getter,@ToString,@EqualsAndHashCode
注解 -
作为预览个性引入
/* 这个类具备两个特色
-
- 所有成员属性都是 final
-
- 全副办法由构造方法,和两个成员属性拜访器组成(共三个)
- 那么这品种就很适宜应用 record 来申明 */
-
final class Rectangle implements Shape {final double length; final double width; public Rectangle(double length, double width) {this.length = length; this.width = width;} double length() { return length;} double width() { return width;}
} /** * 1. 应用 record 申明的类会主动领有下面类中的三个办法
* 2. 在这根底上还附赠了 equals(),hashCode()办法以及 toString()办法
* 3. toString 办法中包含所有成员属性的字符串示意模式及其名称 */ record Rectangle(float length, float width) { }
空指针异样精准提醒
- 通过 JVM 参数中增加
-XX:+ShowCodeDetailsInExceptionMessages
,能够在空指针异样中获取更为具体的调用信息,更快的定位和解决问题a.b.c.i = 99; // 假如这段代码会产生空指针
Exception in thread “main” java.lang.NullPointerException:
Cannot read field 'c' because 'a.b' is null.
at Prog.main(Prog.java:5) // 减少参数后提醒的异样中很明确的告知了哪里为空导致
switch 的加强终于转正
- JDK12 引入的 switch(预览个性)在 JDK14 变为正式版本,不须要减少参数来启用,间接在 JDK14 中就能应用
- 次要是用
->
来代替以前的:
+break
;另外就是提供了 yield 来在 block 中返回值
Before Java 14
switch (day) {case MONDAY: case FRIDAY: case SUNDAY:
System.out.println(6); break; case TUESDAY:
System.out.println(7); break; case THURSDAY: case SATURDAY:
System.out.println(8); break; case WEDNESDAY:
System.out.println(9); break;
}
Java 14 enhancements
switch (day) {case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9);
}
instanceof 加强
- instanceof 次要在类型强转前探测对象的具体类型,而后执行具体的强转
- 新版的 instanceof 能够在判断的是否属于具体的类型同时实现转换
Object obj = “ 我是字符串 ”; if(obj instanceof String str){
System.out.println(str);
}
其余个性
- 从 Java11 引入的 ZGC 作为继 G1 过后的下一代 GC 算法,从反对 Linux 平台到 Java14 开始反对 MacOS 和 Window(个人感觉是终于能够在日常开发工具中先体验下 ZGC 的成果了,尽管其实 G1 也够用)
- 移除了 CMS 垃圾收集器(功成而退)
- 新增了 jpackage 工具,标配将利用打成 jar 包外,还反对不同平台的个性包,比方 linux 下的
deb
和rpm
,window 平台下的msi
和exe
总结
对于预览个性
- 先贴一段 oracle 官网原文:
This is a preview feature, which is a feature whose design, specification, and implementation are complete, but is not permanent, which means that the feature may exist in a different form or not at all in future JDK releases. To compile and run code that contains preview features, you must specify additional command-line options.
- 这是一个预览性能,该性能的设计,规格和实现是残缺的,但不是永久性的,这意味着该性能可能以其余模式存在或在未来的 JDK 版本中基本不存在。要编译和运行蕴含预览性能的代码,必须指定其余命令行选项。
- 就以
switch
的加强为例子,从 Java12 中推出,到 Java13 中将持续加强,直到 Java14 才正式转正进入 JDK 能够放心使用,不必思考后续 JDK 版本对其的改变或批改 - 一方面能够看出 JDK 作为规范平台在减少新个性的谨严态度,另一方面集体认为是对于预览个性应该采取审慎应用的态度。个性的设计和实现容易,然而其理论价值仍然须要在应用中去验证
JVM 虚拟机优化
- 每次 Java 版本的公布都随同着对 JVM 虚拟机的优化,包含对现有垃圾回收算法的改良,引入新的垃圾回收算法,移除老旧的不再实用于明天的垃圾回收算法等
- 整体优化的方向是高效,低时延的垃圾回收体现
- 对于日常的利用开发者可能比拟关注新的语法个性,然而从一个公司角度来说,在思考是否降级 Java 平台时更加思考的是 JVM 运行时的晋升
参考信息
- IBM Developer Java9 https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-9/
- Guide to Java10 https://www.baeldung.com/java-10-overview
- Java 10 新个性介绍 https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-10/index.html
- IBM Devloper Java11 https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-11/index.html
- Java 11 – Features and Comparison:https://www.geeksforgeeks.org/java-11-features-and-comparison/
- Oracle Java12 ReleaseNote https://www.oracle.com/technetwork/java/javase/12all-relnotes-5211423.html#NewFeature
- Oracle Java13 ReleaseNote https://www.oracle.com/technetwork/java/javase/13all-relnotes-5461743.html#NewFeature
- New Java13 Features https://www.baeldung.com/java-13-new-features
- Java13 新个性概述 https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-13/index.html
- Oracle Java14 record https://docs.oracle.com/en/java/javase/14/language/records.html
- java14-features https://www.techgeeknext.com/java/java14-features
- 《2020 最新 Java 根底精讲视频教程和学习路线!》