Java 17 新特性

昨天单列了 Java 17 新特性之密封类型, 继续刷 What's New in JDK 17 - New Features and Enhancements.

switch 模式匹配(预览)

在 Java 21 才正式放出,主动就是原来的 switch...case 语句可以写成表达式的方式,有返回值, 无需每个分支的 break, 并增加模式匹配功能,比如匹配类型,带约束子条件,匹配 record 的字段值等,这里不展开说明,待到详细了解 Java 21 新特性时再深入研究。

新的 macOS 渲染管道

英文是 New macOS Rendering Pipeline, 主要是 Swing API 如果配置系统属性 -Dsun.java2d.meta=true 就可以用 Apple Metal 替代 OpenGL 加速渲染界面,很少写 Java Swing 桌面应用的略过。

新的 API 可访问大图标 

同样是在对 Swing 的改进,可用 FileSystemView 加载解析度的图标

DatagramSocket 可直接加入和离开多播组

写网络应用的可以关注,以前写 Socket 多播应用需使用 java.net.MulticastSocket, 现在的 java.net.DataramSocket 有了两个新的方法

joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)

对于此特性,本人有兴趣稍加深入,什么是多播(又叫组播),它是如何工作的,有何有途。由多播可拓展到单播,广播,任播的概念,这得另启一篇新的日志。

增强伪随机数的生成

为伪随机数生成(PRNGs - pseudorandom number generators) 提供了新的接口类型和实现(如新接口 RandomGenerator 和新类 RandomGeneratorFactory)。还包括 jumpable PRNGs 和额外的 splittable PRNS 算法(LXM)。这个增强与我们实际应用可能不那么紧密。

与 JavaDoc 相关的两个特性

JavaDoc 生成文档时,发现源文件中有问题用 ^ 标识位置,JavaDoc 新加了 New API 页面用来支持 @since 标签,优化了 Deprecated 页面

访问外部函数和内存 API(孵化期)

允许 Java 访问 JVM 外代码和数据,比如不而要脆弱且危险的 JNI 就是调用本地库和数据。这个有点期待,目前都是用 JNI 来调用 C++ 写的共享库,直接在 Java 代码中用该特征调用外部共享库好像有些麻烦,但这会繁荣类似于 JNA, JNR 那样第三方库。

JDK 飞行记录器(Flight Recorder) 支持反序列化事件

原来我们会用 JVisualVM, JConsole, 或商业的 YourKit, Profiler 来分析 JVM 的性能,这需要 Java 程序启用 JMX 扩展,并且对应用性能有一定的影响。Flight Recorder (JDK 11+ 内置, JDK 8u262+ 也支持,需命令行开启) 是内建于 JVM 的性能分析和事件记录工具,几乎没有性能开销,可用于线上生产环境。

启动时启用

java -XX:StartFlightRecording=duration=60s,filename=recording.jfr -jar myapp.jar

运行时启用

jcmd <pid> JFR.start name=profile filename=recording.jfr duration=1m settings=profile

完后停止

jcmd <pid> JFR.stop name=profile

Java 14+ 可以编程方式启动 JFR(Java Flight Recorder),Java 14+ 开始自带了 jfr 命令

Java 17+ 支持通过 jfr 命令附加目标进程采样

jfr start --pid <pid> --duration 1m --filename profile.jfr --settings profile

 飞行数据记录在 recording.jfr 文件中,然手可用 JMC(Java Mission Control http://jdk.java.net/jmc/) 打开 recording.jfr 文件进行分析, 或可用 jfr 和 JVisualVM分析。下面的在 JMC 中打开  recording.jfr 文件时的样子

新增 Console.charset() 方法

它返回由主机环境或用户指定的输入输出字符集,它与  Charset.defaultCharset() 的值可能不用。

Console console = System.console();
var charset = console.charset();

支持本地字符集的系统属性名 native.encoding

比如使用该属性名,在 Linux 或 macOS  下指定为 UTF-8,在 Windows 下指定为 Cp1252

新增 java.time.InstantSource 接口

java.time.InstantSource 成为了抽象类 java.time.Clock 的接口。InstantSource 表明只关注当前时刻,不含时区信息。

新增 16 进制的格式化与解析工具类 java.util.HexFormat

可用它在 16 进制与原始类型或字节数组间转换,还可指定分隔符,前/后缀,大/小写格式

HexFormat.of().toHexDigits(999999); // 000f423f
HexFormat.of().formatHex(new byte[]{56, 72}); // 3848

支持 ARM 64(Apple 芯片) 架构的 macOS

keytool 命令支持新参数 -genkeypair

logging 支持异步刷出日志

这是 log4j2 或 logback 早就支持的功能,为避免日志对业务线程的影响。日志先写入到缓冲中,然后由日志框架在某个时机刷出到控制台,文件或其他目的地。用 -Xlog:async 开启异步输出日志的功能,XX:AsyncLogBufferSize=<bytes> 指定缓冲区多大时刷新。

尽管 JDK 一直很努力的在发展自己的通用日志组件, 并且也在 java.util.logging.SimpleFormatter 中支持 “%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%n” 那么模式配置,编程方式或用 logging.properties 配置文件,但与 slf4j + logback, 或  log4j2 那样的第三方日志框架相比显然是差远了,为何就不放弃呢。或许 JDK 的 java.util.logging 通用框架能得到某些只用 JDK 不引入第三方组件绿党人的青睐。

本文链接 https://yanbin.blog/java-17-new-features/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

guest

0 Comments
Inline Feedbacks
View all comments