JDK的8,11,13,18版本一些主要新增特性:
Java8
-
Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
-
方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
-
默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。
-
新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
-
Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
-
Date Time API − 加强对日期与时间的处理。
-
Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
-
Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
Java 11
-
本地变量类型推断(Local Var)
在Lambda表达式中,可以使用var关键字来标识变量,变量类型由编译器自行推断。
-
字符串加强
String新增了strip()方法,和trim()相比,strip()可以去掉Unicode空格,例如,中文空格:
- 集合加强
自 Java 9 开始,Jdk 里面为集合(List/ Set/ Map)都添加了 of 和 copyOf 方法,它们两个都用来创建不可变的集合,来看下它们的使用和区别。
var list = List.of("Java","Python","C");
var copy = List.copyOf(list);
System.out.println(list == copy); //true
var list = new ArrayList<String>();
var copy = List.copyOf(list);
System.out.println(list == copy);//false
注意:使用of和copyOf创建的集合为不可变集合,不能进行添加、删除、替换、排序等操作,不然会报 java.lang.UnsupportedOperationException 异常。
- Stream 加强
Stream 是 Java 8 中的新特性,Java 9 开始对 Stream 增加了以下 4 个新方法。
- 增加单个参数构造方法,可为null
Stream.ofNullable(null).count(); // 0
- 增加 takeWhile 和 dropWhile 方法
Stream.of(1, 2, 3, 2, 1)
.takeWhile(n -> n < 3)
.collect(Collectors.toList()); // [1, 2]
从开始计算,当 n < 3 时就截止
Stream.of(1, 2, 3, 2, 1)
.dropWhile(n -> n < 3)
.collect(Collectors.toList());// [3, 2, 1]
这个和上面的相反,一旦 n < 3 不成立就开始计算
- iterate重载
这个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。
-
Optional 加强
-
InputStream 加强
InputStream添加了个新的方法:transferTo,可以用来将数据直接传输到 OutputStream,这是在处理原始数据流时非常常见的一种用法,
- HTTP Client API
这是 Java 9 开始引入的一个处理 HTTP 请求的的孵化 HTTP Client API,该 API 支持同步和异步,而在 Java 11 中已经为正式可用状态,可以在 java.net 包中找到这个 API。
- 读写文件
对Files类增加了writeString和readString两个静态方法,可以直接把String写入文件,或者把整个文件读出为一个String:
- 单文件代码
这个功能允许直接使用java解析器运行java代码。java文件会在内存中执行编译并且直接执行。唯一的约束在于所有相关的类必须定义在一个java文件中。
Java13
- Dynamic CDS Archives(动态 CDS 归档)
首先介绍一下 CDS,CDS 全名为 Class Data Sharing,目的是减少Java编程语言应用程序的启动时间,特别是较小的应用程序,并减少内存占用。实现思路是通过JVM调用期间,将共享的归档文件被映射到内存中,从而节省了加载这些类的成本,并允许多个 JVM 进程共享这些类的大部分 JVM 元数据。
- ZGC: Uncommit Unused Memory
在JDK 11中,Java引入了ZGC,这是一款可伸缩的低延迟垃圾收集器,但是当时只是实验性的。并且,ZGC释放的内存是不会还给操作系统的。
而在Java 13中,JEP 351再次对ZGC做了增强,本次 ZGC 可以将未使用的堆内存返回给操作系统。
- Reimplement the Legacy Socket API
使用易于维护和调试的更简单、更现代的实现替换 java.net.Socket 和
java.net.ServerSocket API。
java.net.Socket和java.net.ServerSocket的实现非常古老,这个JEP为它们引入了一个现代的实现。现代实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来使用它们。
- Switch Expressions (Preview)
在JDK 12中引入了Switch表达式作为预览特性。JEP 354修改了这个特性,它引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield, switch语句(不返回值)应该使用break。
int i = switch (x) {
case "1": yield 1;
case "2": yield 2;
default: {
int len = args[1].length();
yield len;
}
};
- Text Blocks
text block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。
以前从外部copy一段文本串到Java中,会被自动转义,如下:
"<html>\n"
" <body>\n"
" <p>Hello, world</p>\n"
" </body>\n"
"</html>\n";
在JDK 13中,就可以使用以下语法了:
"""
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
Java18
JEP 400:
指定 UTF-8 作为标准 Java API 的默认字符集。通过此更改,依赖于默认字符集的 API
将在所有实现、操作系统、区域设置和配置中保持一致。
JEP 408:
引入一个简单的 Web 服务器。提供一个命令行工具,来启动一个只提供静态文件的最小网络服务器,它没有 CGI 或类似 servlet
的功能可用。该工具用于原型设计、临时编码和测试目的,尤其是在教学环境中。
JEP 413:
支持在 Java API 文档中加入代码片段。为 JavaDoc 的 Standard Doclet 引入一个 @snippet
标记,以简化 API 文档中嵌入示例源代码的难度。
JEP 416 :
用方法句柄重新实现核心反射。在 java.lang.invoke 的方法句柄之上,重构 java.lang.reflect
的方法、构造函数和字段,使用方法句柄处理反射的底层机制将减少 java.lang.reflect 和 java.lang.invoke
两者的 API 维护和开发成本
。
JEP 417:
Vector API(第三孵化器)。引入一个 API 来表达向量计算,这些计算在运行时可以编译为支持的 CPU
架构上的最佳向量指令,从而实现优于等效标量计算的性能。
JEP 418:
互联网地址解析 SPI。定义用于主机名和地址解析的服务提供者接口
(SPI),以便java.net.InetAddress可以使用平台内置解析器以外的解析器。
JEP 419:
外部函数和内存 API(第二孵化器)。引入了一个新 API, Java 程序可以通过它与 Java
运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即 JVM 外的代码),并安全地访问外部内存(即不由 JVM
管理的内存),外部函数和内存 API 使 Java 程序能够调用本机库并处理本机数据,而不具有 JNI 的脆弱性和危险。
JEP 420:
switch 模式匹配表达式。使用 switch 表达式和语句的模式匹配以及对模式语言的扩展来增强 Java 编程语言。将模式匹配扩展到
switch 允许针对多个模式测试表达式,每个模式都有特定的操作,可以简洁安全地表达复杂的面向数据的查询。
JEP 421:
弃用 Finalization 功能。Java 1.0 中引入的 Finalization
旨在帮助避免资源泄漏问题,然而这个功能存在延迟不可预测、行为不受约束,以及线程无法指定等缺陷,导致其安全性、性能、可靠性和可维护性方面都存在问题,因此将其弃用,用户可选择迁移到其他资源管理技术,例如try-with-resources
语句和清洁器。