点赞 再看,能源有限。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/proj…
此文章属于 Java 新个性教程 系列,会介绍 Java 每个版本的新性能,能够点击浏览。
<!– more –>
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,次要起因如下:
- Mercurial 生成的版本控制元数据过大。
- Mercurial 相干的开发工具比拟少,而 Git 简直在所有的支流 IDE 中曾经无缝集成。
- Mercurial 相干的服务比拟少,无论是自建托管,还是服务托管。
为了优雅的迁徙到 Git,OpenJDK 做了如下操作。
- 将所有的单存储库 OpenJDK 我的项目从 Mercurial 迁徙到 Git。
- 保留所有的版本控制历史,也包含 Tag。
- 依据 Git 的最佳实际从新格式化提交的音讯。
- 创立了一个工具用来在 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 语言函数办法,而后输入运行后果的例子。
- 编写一个 C 函数打印一个 “hello www.wdbyte.com”。
#include <stdio.h>
void printHello(){printf("hello www.wdbyte.com\n");
}
- 将下面的代码编译,而后输入到共享库 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
- 编写一个 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();}
}
}
- Java 代码编译。
$ javac --add-modules jdk.incubator.foreign JEP389.java
正告: 应用 incubating 模块: jdk.incubator.foreign
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
常见平台格局如下:
- Linux:
deb
andrpm
- macOS:
pkg
anddmg
- Windows:
msi
andexe
要留神的是,
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 中再次孵化。
此提案的指标如下:
- 通用:单个 API 应该可能对各种内部内存(如本机内存、长久内存、堆内存等)进行操作。
- 平安:无论操作何种内存,API 都不应该毁坏 JVM 的安全性。
- 管制:能够自在的抉择如何开释内存(显式、隐式等)。
- 可用:如果须要拜访内部内存,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
hashcode
、equals
、toString
等办法,缩小了代码编写量。
示例:编写一个 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 新个性介绍
参考
- https://openjdk.java.net/proj…
- https://docs.oracle.com/en/ja…
< 完 >
Hello world : ) 我是阿朗,一线技术工具人,认认真真写文章。
点赞 的个个都是人才,不仅长得帅气难看,谈话还好听。
文章继续更新,能够关注公众号「程序猿阿朗」或拜访「程序猿阿朗博客](https://www.wdbyte.com)」。
回复【材料】有我筹备的各系列知识点和必看书籍。
本文 Github.com/niumoo/JavaNotes 曾经收录,有很多知识点和系列文章,欢送 Star。