Java 语言和平台在不断发展。Java 的新版本现在大约每 6 个月发布一次。以下部分将列出最新 Java 版本的主要新增内容。
Java 18 中的新功能
1、弃用最终确定以进行删除(Deprecate Finalization for Removal)
JEP 421: Deprecate Finalization for Removalhttp://openjdk.java.net/jeps/421 2、互联网地址解析 SPI
3、开关模式匹配 - 第二次预览
4、使用方法句柄重新实现核心反射
5、小型、简单的 Web 服务器,只能提供静态内容
6、外存API(第二个孵化器)
7、Vector API(第 3 个孵化器)
8、UTF-8 作为 Java API 的标准字符集
9、通过 @snippet 标记在 JavaDoc 注释中的代码片段
Java 17 中的新功能
1、始终恢复严格的浮点语义。
2、增强的伪随机数生成器
3、新的 MacOS 渲染管道
4、macOS/AArch64 端口
5、弃用 Applet API 以进行删除
6、强烈封装JDK内部
7、开关的模式匹配
8、删除 RMI 激活
9、密封类
10、删除实验性 AOT 和 JIT 编译器
11、弃用 SecurityManager 以进行删除
12、外来函数和内存API(孵化器)
13、用于 SIMD 指令访问的矢量 API(第二个孵化器)
14、特定于上下文的反序列化过滤器
Java 16 中的新功能
用于从 Java 应用程序为 Windows、Mac 和 Linux 生成本机安装程序的打包工具。
对 Java Stream API 的改进。
Java Records 不再是预览版,现在是永久功能。
Vector API(孵化器状态)——用于访问底层硬件的 CPU SIMD 操作。
ZGC 并发线程堆栈处理。
Unix 域套接字通道。
外部链接器 API(孵化器)。
外部内存访问 API(第三个孵化器)。
通过 Java 反射代理对象调用默认方法。
操作员的模式匹配instanceof现在不在预览中,并且是永久功能。
密封类在第二个预览中。
Java 15 中的新功能
密封类(预览版)
隐藏类
爱德华兹曲线数字签名算法 (EdDSA)。
重新实现旧版 DatagramSocket API
instanceof 的模式匹配(第二次预览)
记录(第二次预览)
Foreign-Memory Access API(第二个孵化器)
文本块
ZGC:可扩展的低延迟垃圾收集器
Shenandoah:一个低暂停时间的垃圾收集器
禁用和弃用偏向锁定
移除 Nashorn JavaScript 引擎
移除了 Solaris 和 Sparc 端口
弃用 RMI 激活以进行删除
Java 14 中的新功能
记录- 浅不可变类(预览版)。
NullPointerException 改进。
文本块 - 更容易声明多行字符串。
Java switch 表达式成为一个永久的特性。
Java instanceof 运算符的增强模式匹配。
通过 FileChannel API 的非易失性内存映射字节缓冲区。
外部内存访问 API 用于访问 Java VM 堆之外的内存。
G1 垃圾收集器的 NUMA 感知内存分配。
Java Flight Recorder - 事件流。
用于将 Java 应用程序打包为自包含应用程序的打包工具。
将 Z 垃圾收集器 (ZGC) 移植到 MacOS 和 Windows
删除并发标记和清除垃圾收集器。
删除用于 JAR 文件的 pack200 / unpack200 zip 工具。
弃用 Java 的 Solaris/Sparc、Solaris/x64 和 Linux/Sparc 端口。
下面链接是Java14中更改的完整列表。
JDK 14https://openjdk.java.net/projects/jdk/14/
Java 13 中的新功能
Java 开关表达式已被修改 - 不是 100% 向后兼容 Java 12。
文本块 - 更容易声明多行字符串。
旧版 Socket API 的重新实现。新的实现更简洁,并且应该更好地与用户空间线程(例如纤维)一起工作,这些线程正在 Project Loom 中进行探索(将来可能添加到 Java)。
Z 垃圾收集器现在将未使用的内存释放回操作系统,当长时间未使用时。
下面链接是Java13中更改的完整列表。
JDK 13https://openjdk.java.net/projects/jdk/13/
Java 12 中的新功能
一种称为 Shenandoah 的低暂停时间垃圾收集器(仅限 OpenJDK)。
Java 开关表达式(预览版 - 可能会再次从 Java 中删除)。
JVM 常量 API。
G1 中的可中止混合收集(垃圾收集)。
立即从 G1 返回未使用的已提交内存。
下面链接是Java12中更改的完整列表。
JDK 12https://openjdk.java.net/projects/jdk/12/
Java 11 中的新功能
从 JDK 中删除了 Java EE 和 Corba 模块。
HttpClient已成为标准(Java 9 中添加的标准)。
JDK11的HttpClient的使用 var允许作为 lambda 表达式参数类型的Java关键字。
通过椭圆曲线密码学的密钥协商。
统一码 10。
新的密码算法。
启动单文件源代码程序(执行时编译)。
TLS 1.3 支持。
弃用 Nashorn JavaScript 引擎
下面链接是Java11中更改的完整列表。
JDK 11https://openjdk.java.net/projects/jdk/11/
Java 10 中的新功能
1、局部变量类型推断
2、G1(垃圾收集器)的并行完整垃圾收集
3、Graal 作为实验性 JIT 编译器包含在内
4、一些内部、JVM 和平台级别的更改
下面链接是Java10中更改的完整列表。
JDK 10http://openjdk.java.net/projects/jdk/10/
Java 9 中的新功能
1、Java 模块
2、Java 反射模块类
3、Java 尝试资源增强
4、Java 紧凑字符串
5、JDK 中包含的Java Microbenchmark Harness (JMH)
下面链接是Java9中更改的完整列表。
JDK 9http://openjdk.java.net/projects/jdk9/
Java 8 中的新功能
1、Java Lambda 表达式
2、引入java.time包,提供了线程安全的日期API
3、Java Streams(功能流)
4、JavaFX(与 Java 8 中的 Java SE 捆绑在一起)
5、Nashorn JavaScript 引擎。
从 JDK 1.8 开始,Nashorn取代Rhino(JDK 1.6, JDK1.7) 成为 Java 的嵌入式 JavaScript 引擎。Nashorn 完全支持 ECMAScript 5.1 规范以及一些扩展。它使用基于 JSR 292 的新语言特性,其中包含在 JDK 7 中引入的 invokedynamic,将 JavaScript 编译成 Java 字节码。
此功能在Java11中弃用了。最终在Java15中被移除掉了。
Java 7 中的新功能
1、Try with resources
2、捕获多个异常
3、Java Fork 和通过 ForkJoinPool 加入
4、Java switch语句中的字符串
5、Java NIO 2.0 中的新文件系统 API
6、泛型声明中的类型推断(所谓的“菱形”运算符)
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Map<String, List<String>> myMap = new HashMap<>();
7、带有下划线的数字文字作为视觉分隔符(例如 1_000_000)
//没太大用处
int vision = 123_45_67;
8、二进制数字文字(例如 0b10100101)
此功能对于面向比特的系统(如处理器,网络协议和位图硬件设备)非常有用。在这之前程序员经常要将二进制转换为十进制/十六进制,反之亦然。使用此功能将删除此转换,并且此转换中出错的可能性会降低。
此外,使用此功能,使用按位运算的代码将更具可读性。
public static void main(String[] args) {
int i=0b0111;
byte b=(byte) 0b0111;
long l=(long) 0B0111L;
System.out.println("i="+i);
System.out.println("b="+b);
System.out.println("l="+l);
}
9、支持 Java 虚拟机 (JVM) 中的动态类型语言
JDK1.7中新加入的java.lang.invoke包的主要目的就是在之前单纯依靠符号引用来确定的目标方法这种方式以外,提供一种新的动态确定目标方法的机制,称之为MethodHandle。其实MethodHandle就是类似C/C++中的函数指针,或者C#中的委托。
如下代码演示了MethodHandle的基本用法,无论obj是何种类型,都可以正确的调用到println()方法。
package demo;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import static java.lang.invoke.MethodHandles.lookup;
public class MethodHandleTest {
static class ClassA{
public void println(String s){
System.out.println(s);
}
}
public static void main(String[] args) throws Throwable {
Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA();
//无论obj最终是哪个实现类,下面这句都能正确调用到println方法
getPrintlnMH(obj).invokeExact("test");
}
private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable{
//MethodType: 代表"方法类型",包含了方法的返回值(methodType()的第一个参数)和具体参数(methodType()第二个及以后的参数)
MethodType mt = MethodType.methodType(void.class,String.class);
//lookup()方法来自于MethodHandles.lookup,这句的作用是在指定类中查找符合给定的方法名称、方法类型、并且符合调用权限的方法语柄
/*因为这里调用的是一个虚方法,按照Java语言的规则,方法第一个参数是隐式的,代表该方法的接受者,也即是this指向的对象,这个参数以前是放在
参数列表中进行传递的,而现在提供了bindTo方法来完成这件事情*/
return lookup().findVirtual(reveiver.getClass(),"println",mt).bindTo(reveiver);
}
}