点赞再看, 动力无限. Hello world : ) 微信搜「 程序猿阿朗 」.
本文 GitHub.com/niumoo/JavaNotes 和 程序猿阿朗博客 已经收录, 有很多知识点和系列文章.
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 代码中使用的具体说明.
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 哈希之间进行转换.
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).
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 发行版也适用.
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
- @jdk.internal.ValueBased
- public final class Optional<T> {
- // ...
- }
- Linux: deb and rpm
- macOS: pkg and dmg
- Windows: msi and exe
- 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);
- }
- }
- $ javac JEP392.java
- $ java JEP392.java
- $ jar cvf JEP392.jar JEP392.class
- $ ~/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
- Linux: /opt
- MacOS : /Applications
- Windows: C:\Program Files\
- if (obj instanceof String) {
- String s = (String) obj; // grr...
- ...
- }
- if (obj instanceof String s) {
- // Let pattern matching do the work!
- ...
- }
- package com.wdbyte;
- public record Dog(String name, Integer age) {
- }
- 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);
- }
- }
- https://openjdk.java.net/proj...
- https://docs.oracle.com/en/ja...
- <完>
来源: https://segmentfault.com/a/1190000040891397