JDK16新特性

传送门

SpringMVC的源码解析(精品)
Spring6的源码解析(精品)
SpringBoot3框架(精品)
MyBatis框架(精品)
MyBatis-Plus
SpringDataJPA
SpringCloudNetflix
SpringCloudAlibaba(精品)
Shiro
SpringSecurity
java的LOG日志框架
Activiti(敬请期待)
JDK8新特性
JDK9新特性
JDK10新特性
JDK11新特性
JDK12新特性
JDK13新特性
JDK14新特性
JDK15新特性
JDK16新特性
JDK17新特性
JDK18新特性
JDK19新特性
JDK20新特性
JDK21新特性
其他技术文章传送门入口

前言

Java 16 在 2021 年 3 月 16 日正式发布,非长期支持(LTS)版本。
相关阅读:OpenJDK Java 16 文档
在这里插入图片描述

一、向量 API(第一次孵化)

向量(Vector) API 最初由 JEP 338 提出,并作为孵化 API集成到 Java 16 中。第二轮孵化由 JEP 414 提出并集成到 Java 17 中,第三轮孵化由 JEP 417 提出并集成到 Java 18 中,第四轮由 JEP 426 提出并集成到了 Java 19 中。该孵化器 API 提供了一个 API 的初始迭代以表达一些向量计算,这些计算在运行时可靠地编译为支持的 CPU 架构上的最佳向量硬件指令,从而获得优于同等标量计算的性能,充分利用单指令多数据(SIMD)技术(大多数现代 CPU 上都可以使用的一种指令)。尽管 HotSpot 支持自动向量化,但是可转换的标量操作集有限且易受代码更改的影响。该 API 将使开发人员能够轻松地用 Java 编写可移植的高性能向量算法。

备注:在 Java 18 新特性有详细介绍。

二、启用 C++ 14 语言特性

Java 16 允许在 JDK 的 C++ 源代码中使用 C++14 语言特性,并提供在 HotSpot 代码中可以使用哪些特性的具体指导。

在 Java 15 中,JDK 中 C++ 代码使用的语言特性仅限于 C++98/03 语言标准。它要求更新各种平台编译器的最低可接受版本。

三、ZGC 并发线程堆栈处理

Java16 将 ZGC 线程栈处理从安全点转移到一个并发阶段,甚至在大堆上也允许在毫秒内暂停 GC 安全点。消除 ZGC 垃圾收集器中最后一个延迟源可以极大地提高应用程序的性能和效率。

四、弹性元空间

自从引入了 Metaspace 以来,根据反馈,Metaspace 经常占用过多的堆外内存,从而导致内存浪费。弹性元空间这个特性可将未使用的 HotSpot 类元数据(即元空间,metaspace)内存更快速地返回到操作系统,从而减少元空间的占用空间。

五、对基于值的类发出警告

以下介绍摘自:实操 | 剖析 Java16 新语法特性,原文写的很不错,推荐阅读。

早在 Java9 版本时,Java 的设计者们就对 @Deprecated 注解进行了一次升级,增加了 since 和 forRemoval 等 2 个新元素。其中,since 元素用于指定标记了 @Deprecated 注解的 API 被弃用时的版本,而 forRemoval 则进一步明确了 API 标记 @Deprecated 注解时的语义,如果forRemoval=true时,则表示该 API 在未来版本中肯定会被删除,开发人员应该使用新的 API 进行替代,不再容易产生歧义(Java9 之前,标记 @Deprecated 注解的 API,语义上存在多种可能性,比如:存在使用风险、可能在未来存在兼容性错误、可能在未来版本中被删除,以及应该使用更好的替代方案等)。

仔细观察原始类型的包装类(比如:java.lang.Integer、java.lang.Double),不难发现,其构造函数上都已经标记有@Deprecated(since=“9”, forRemoval = true)注解,这就意味着其构造函数在将来会被删除,不应该在程序中继续使用诸如new Integer();这样的编码方式(建议使用Integer a = 10;或者Integer.valueOf()函数),如果继续使用,编译期将会产生’Integer(int)’ is deprecated and marked for removal 告警。并且,值得注意的是,这些包装类型已经被指定为同 java.util.Optional 和 java.time.LocalDateTime 一样的值类型。

其次,如果继续在 synchronized 同步块中使用值类型,将会在编译期和运行期产生警告,甚至是异常。在此大家需要注意,就算编译期和运行期没有产生警告和异常,也不建议在 synchronized 同步块中使用值类型,举个自增的例子。示例 1-5:

public void inc(Integer count) {
    for (int i = 0; i < 10; i++) {
        new Thread(() -> {
            synchronized (count) {
                count++;
            }
        }).start();
    }
}

当执行上述程序示例时,最终的输出结果一定会与你的期望产生差异,这是许多新人经常犯错的一个点,因为在并发环境下,Integer 对象根本无法通过 synchronized 来保证线程安全,这是因为每次的count++操作,所产生的 hashcode 均不同,简而言之,每次加锁都锁在了不同的对象上。因此,如果希望在实际的开发过程中保证其原子性,应该使用 AtomicInteger。

六、打包工具

在 Java 14 中,JEP 343 引入了打包工具,命令是 jpackage。在 Java 15 中,继续孵化,现在在 Java 16 中,终于成为了正式功能。这个打包工具允许打包自包含的 Java 应用程序。它支持原生打包格式,为最终用户提供自然的安装体验,这些格式包括 Windows 上的 msi 和 exe、macOS 上的 pkg 和 dmg,还有 Linux 上的 deb 和 rpm。它还允许在打包时指定启动时参数,并且可以从命令行直接调用,也可以通过 ToolProvider API 以编程方式调用。注意 jpackage 模块名称从 jdk.incubator.jpackage 更改为 jdk.jpackage。这将改善最终用户在安装应用程序时的体验,并简化了“应用商店”模型的部署。关于这个打包工具的实际使用,可以看这个视频 Playing with Java 16 jpackage(需要梯子)

七、外部内存访问 API(第三次孵化)

引入外部内存访问 API 以允许 Java 程序安全有效地访问 Java 堆之外的外部内存。

Java 14(JEP 370) 的时候,第一次孵化外部内存访问 API,Java 15 中进行了第二次复活(JEP 383),在 Java 16 中进行了第三次孵化。

引入外部内存访问 API 的目的如下:

  • 通用:单个 API 应该能够对各种外部内存(如本机内存、持久内存、堆内存等)进行操作。
  • 安全:无论操作何种内存,API 都不应该破坏 JVM 的安全性。
  • 控制:可以自由的选择如何释放内存(显式、隐式等)。
  • 可用:如果需要访问外部内存,API 应该是 sun.misc.Unsafe.

八、instanceof 模式匹配(转正)

JDK 版本更新类型JEP更新内容
Java SE 14previewJEP 305首次引入 instanceof 模式匹配。
Java SE 15Second PreviewJEP 375相比较上个版本无变化,继续收集更多反馈。
Java SE 16Permanent ReleaseJEP 394模式变量不在隐式为 final。

从 Java 16 开始,你可以对 instanceof 中的变量值进行修改。

        String o = "";
        // 原来
        if (o instanceof String) {
            String s = (String) o;
        }
        Object c = null;
        c = "";
        // 新的
        if (c instanceof String b) {
            b = "b";
            System.out.println("c=" + c);// c=
            System.out.println("b=" + b);// b=b
        }

九、记录类型(转正)

记录类型变更历史:

JDK 版本更新类型JEP更新内容
Java SE 14previewJEP 359引入 record 关键字,record 提供一种紧凑的语法来定义类中的不可变数据。
Java SE 15Second PreviewJEP 384支持在局部方法和接口中使用 record。
Java SE 16Permanent ReleaseJEP 395非静态内部类可以定义非常量的静态成员。

从 Java SE 16 开始,非静态内部类可以定义非常量的静态成员。

public class Outer {
 
class Inner {
 
static int age;
 
}
 
}

在 JDK 16 之前,如果写上面这种代码,IDE 会提示你静态字段 age 不能在非静态的内部类中定义,除非它用一个常量表达式初始化。

十、默认强封装 JDK 内部元素

此特性会默认强封装 JDK 的所有内部元素,但关键内部 API(例如 sun.misc.Unsafe)除外。默认情况下,使用早期版本成功编译的访问 JDK 内部 API 的代码可能不再起作用。鼓励开发人员从使用内部元素迁移到使用标准 API 的方法上,以便他们及其用户都可以无缝升级到将来的 Java 版本。强封装由 JDK 9 的启动器选项–illegal-access 控制,到 JDK 15 默认改为 warning,从 JDK 16 开始默认为 deny。(目前)仍然可以使用单个命令行选项放宽对所有软件包的封装,将来只有使用–add-opens 打开特定的软件包才行。

十一、密封类(预览)

密封类由 JEP 360 提出预览,集成到了 Java 15 中。在 JDK 16 中, 密封类得到了改进(更加严格的引用检查和密封类的继承关系),由 JEP 397 提出了再次预览。

十二、其他优化与改进

  • JEP 380:Unix-Domain 套接字通道:Unix-domain 套接字一直是大多数 Unix 平台的一个特性,现在在 Windows 10 和 Windows Server 2019 也提供了支持。此特性为 java.nio.channels 包的套接字通道和服务器套接字通道 API 添加了 Unix-domain(AF_UNIX)套接字支持。它扩展了继承的通道机制以支持 Unix-domain 套接字通道和服务器套接字通道。Unix-domain 套接字用于同一主机上的进程间通信(IPC)。它们在很大程度上类似于 TCP/IP,区别在于套接字是通过文件系统路径名而不是 Internet 协议(IP)地址和端口号寻址的。对于本地进程间通信,Unix-domain 套接字比 TCP/IP 环回连接更安全、更有效
  • JEP 389:外部链接器 API(孵化): 该孵化器 API 提供了静态类型、纯 Java 访问原生代码的特性,该 API 将大大简化绑定原生库的原本复杂且容易出错的过程。Java 1.1 就已通过 Java 原生接口(JNI)支持了原生方法调用,但并不好用。Java 开发人员应该能够为特定任务绑定特定的原生库。它还提供了外来函数支持,而无需任何中间的 JNI 粘合代码。
  • JEP 357:从 Mercurial 迁移到 Git:在此之前,OpenJDK 源代码是使用版本管理工具 Mercurial 进行管理,现在迁移到了 Git。
  • JEP 369:迁移到 GitHub:和 JEP 357 从 Mercurial 迁移到 Git 的改变一致,在把版本管理迁移到 Git 之后,选择了在 GitHub 上托管 OpenJDK 社区的 Git 仓库。不过只对 JDK 11 以及更高版本 JDK 进行了迁移。
  • JEP 386:移植 Alpine Linux:Alpine Linux 是一个独立的、非商业的 Linux 发行版,它十分的小,一个容器需要不超过 8MB 的空间,最小安装到磁盘只需要大约 130MB 存储空间,并且十分的简单,同时兼顾了安全性。此提案将 JDK 移植到了 Apline Linux,由于 Apline Linux 是基于 musl lib 的轻量级 Linux 发行版,因此其他 x64 和 AArch64 架构上使用 musl lib 的 Linux 发行版也适用。
  • JEP 388:Windows/AArch64 移植:这些 JEP 的重点不是移植工作本身,而是将它们集成到 JDK 主线存储库中;JEP 386 将 JDK 移植到 Alpine Linux 和其他使用 musl 作为 x64 上主要 C 库的发行版上。此外,JEP 388 将 JDK 移植到 Windows AArch64(ARM64)。

参考大神文献: https://javaguide.cn/java/new-features/java16.html
其他文献:
Java Language Changes
Consolidated JDK 16 Release Notes
Java 16 正式发布,新特性一一解析
实操 | 剖析 Java16 新语法特性(写的很赞)

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JDK 16Java Development Kit (JDK) 的一个版本,其中包含了一些新的特性和改进。下面是 JDK 16 中一些主要的新特性的详细解析: 1. JEP 338: Unix-Domain Socket Channels 这个 JEP 引入了一种新的通道类型,用于在本地进程之间进行高性能的通信。它可以在 Unix 系统上使用,通过 Unix 域套接字 (UNIX domain socket) 实现。这种通信方式比传统的网络套接字 (socket) 更高效,并且更适合在同一台机器上的进程之间进行通信。 2. JEP 376: ZGC: Concurrent Thread-Stack Processing 这个 JEP 对 Z Garbage Collector (ZGC) 进行了改进,引入了并发线程栈处理的功能。它可以在应用程序运行时并发地处理线程栈信息,从而减少了垃圾收集器的停顿时间,提高了应用程序的响应性能。 3. JEP 338: Pattern Matching for instanceof 这个 JEP 引入了一种新的语法,使得在使用 instanceof 操作符时更加方便和简洁。它允许我们在对对象进行类型检查的同时,将对象转换为指定的类型,并且可以直接在条件语句中使用。 4. JEP 338: Strong encapsulation of JDK internals 这个 JEP 加强了 JDK 内部实现的封装,限制了访问 JDK 内部 API 的能力。这样做的目的是为了提高 JDK 的安全性和稳定性,并且鼓励开发者使用公共的 API,而不是依赖于不稳定的内部实现。 5. JEP 338: Unix-Domain Socket Channels 这个 JEP 引入了一种新的通道类型,用于在本地进程之间进行高性能的通信。它可以在 Unix 系统上使用,通过 Unix 域套接字 (UNIX domain socket) 实现。这种通信方式比传统的网络套接字 (socket) 更高效,并且更适合在同一台机器上的进程之间进行通信。 这些是 JDK 16 中的一些主要特性和改进,它们提供了更好的性能、更简洁的语法和更强大的安全性。但请注意,这只是其中一部分特性,还有其他一些特性和改进没有在这里提到。如需了解更多详细信息,请参阅 JDK 16 的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝影铁哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值