JDK14新特性(What's New In JDK 14)

JDK14新特性

  • Pattern Matching for instanceof (Preview)
  • Non-Volatile Mapped Byte Buffers (Incubator)
  • Helpful NullPointerExceptions
  • Switch Expressions (Standard)
  • Packaging Tool (Incubator)
  • NUMA-Aware Memory Allocation for G1
  • JFR Event Streaming
  • Records (Preview)
  • Deprecate the Solaris and SPARC Ports
  • Remove the Concurrent Mark Sweep (CMS) Garbage Collector
  • ZGC on macOS (experimental)
  • ZGC on Windows (experimental)
  • Deprecate the ParallelScavenge + SerialOld GC Combination
  • Remove the Pack200 Tools and API
  • Text Blocks (Second Preview)
  • Foreign-Memory Access API (Incubator)

2020年3月17日,Java 14(Java SE 14)及其Java开发工具包14(JDK 14)开源发布。本文主要记录了JDK14的16个新特性。

本文的IDE为IDEA2020.1,JDK14是通过IDE下载的Open JDK.

Pattern Matching for instanceof (Preview)

instanceof的模式匹配(预览版)

String s = "instance";
//before jdk14
if (s instanceof String) {
    String str = s;
    System.out.println("before jdk14:" + str);
}
//in jdk14
if (s instanceof String str) {
    System.out.println("before jdk14:" + str);
}
if (s instanceof String str && str.equals("instance")) {
    System.out.println("TRUE");
}

仅当object不为null时,instanceOf才会匹配,然后仅将其分配给str。 在instanceof中使用模式匹配应减少Java程序中显式强制转换的总数。

Non-Volatile Mapped Byte Buffers (Incubator)

新增了java.base/jdk/internal/misc/ExtendedMapMode.java以支持MappedByteBuffer访问non-volatile
memory (NVM)。

从JDK1.4开始,Java引入了NIO文件相关的API,带有MappedByteBuffer的FileChannel将文件数据的一部分加载到虚拟内存中,然后引入了称为Path的新增强功能。 当我们使用Java NIO时,Path是一个接口,它将java.io.File类替换为文件或目录的表示形式。
现在,Java 14对MappedByteBuffer进行了增强,以将部分文件数据加载到非易失性内存(NVM)中。 非易失性存储器或非易失性存储器是计算机存储器,即使关闭电源(例如ROM(只读存储器),闪存,硬盘等存储设备)也不会丢失/删除数据。 如果像RAM一样关闭电源,则无法保留数据。 唯一需要的API更改是FileChannel客户端采用的新枚举,以请求映射位于NVM支持的文件系统而不是传统文件存储系统上的文件。

Helpful NullPointerExceptions

JVM生成的NullPointerExceptions(NPE)异常消息的改进。可以更好地提示哪个地方出现的空指针,需要通过-XX:+ShowCodeDetailsInExceptionMessages开启。 对于程序过早终止,这将对开发人员和支持人员有帮助的信息。 由于NPE几乎可以出现在程序中的任何位置,因此尝试捕获它们并从中恢复通常是不切实际的。

//NullPointerExceptions
pojo p = new pojo(null);
System.out.println(p.getApple().getColor());

在此之前,报错时这样的:
在这里插入图片描述
现在在运行参数中配置:-XX:+ShowCodeDetailsInExceptionMessages,开启Helpful NullPointerExceptions:
JDK14新特性(What's New In JDK 14)_第1张图片
开启之后,运行结果是这样的:
在这里插入图片描述
如图所示,准确的告知了我们哪个变量为null。

Switch Expressions (Standard)

JDK14扩展了switch语句,在JDK12种已引入,在JDK14中变为了正式版。现在的case中使用->来替代以前的:+break,而且提供了yield来在block中返回值;

//switch
//before JDK14
Calendar calendar = Calendar.getInstance();
Integer today = calendar.get(Calendar.DAY_OF_WEEK);
String weekday = "";
switch (today) {
    case Calendar.MONDAY:
    case Calendar.TUESDAY:
    case Calendar.WEDNESDAY:
    case Calendar.THURSDAY:
    case Calendar.FRIDAY:
        weekday = "weekday";
        break;
    case Calendar.SATURDAY:
    case Calendar.SUNDAY:
        weekday = "weekend";
        break;
    default:
        throw new IllegalStateException("Unexpected value: " + today);
}
System.out.println("Before JDK14:"+weekday);
//in JDK14
weekday = switch (today) {
    case Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY -> "weekday";
    case Calendar.SATURDAY, Calendar.SUNDAY -> "weekend";
    default -> {
        yield "unknown";
        //throw new IllegalStateException("Unexpected value: " + Calendar.DAY_OF_WEEK);
    }
};
System.out.println("JDK14:"+weekday);

Packaging Tool (Incubator)

打包工具(孵化中)

JDK14引入了jdk.incubator.jpackage.jmod,它基于JavaFX javapackager tool构建,目的在于创建一个简单的打包工具。
jpackage工具将Java应用程序捆绑到特定于平台的程序包中,其中包含所需的所有依赖项。作为一组普通的JAR文件或作为模块的集合。
可以用于构建以下文件格式的安装文件:

  • Linux: deb and rpm
  • macOS: pkg and dmg
  • Windows: msi and exe

非模块化的app的构建示例如下:

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

NUMA-Aware Memory Allocation for G1

NUMA-Aware Memory Allocation(NUMA)是一种将微处理器集群配置为多处理系统的方法,因此可以在本地共享内存,可以提高性能并扩展系统的功能。
Java 14提供了可识别NUMA的内存分配功能,以提高大型计算机上的G1性能。
G1的堆组织为固定大小区域的集合。一个区域通常是一组物理页面,尽管使用大页面(通过-XX:+ UseLargePages)时,多个区域可能组成一个物理页面。
如果指定了+ XX:+ UseNUMA选项,则在初始化JVM时,区域将平均分布在可用NUMA节点的总数上。

JFR Event Streaming

JDK11引入了JFR,使用的时候先dump到磁盘上然后再分析;而在JDK14则支持stream方式来进行进程内和进程外应用程序的持续性监控。

Records (Preview)

JDK14引入了预览版本的record类型。在开发中,我们需要编写许多重复代码,编写简单的实体类:构造函数,getter 和 setter,equals(),hashCode(),toString()等。为避免这种重复代码,Java计划使用Records。

在此前的实体类:
JDK14新特性(What's New In JDK 14)_第2张图片
而在JDK14的预览版中,只需一行代码就可以实现等同于以上的效果。
在这里插入图片描述
让我们来看看编译后的AppleRecord实体类,它长这样:
JDK14新特性(What's New In JDK 14)_第3张图片
可以看到AppleRecord继承了java.lang.Record,而且生成了final的hashCode()及equals()方法,但是却没有了setter方法,getter方法也省略了get前缀。

Deprecate the Solaris and SPARC Ports

废弃Solaris / SPARC,Solaris / x64和Linux / SPARC端口,以便将来删除。

通过取消对这些端口的支持,OpenJDK社区中的贡献者将能够加速新功能的开发,以推动平台向前发展。

构建配置更改

以下内容会导致尝试配置Solaris和/或SPARC:

$ bash ./configure
...
checking compilation type... native
configure: error: The Solaris and SPARC ports are deprecated and may be removed in a future release. \
Use --enable-deprecated-ports=yes to suppress this error.
configure exiting with result code 1
$

新的–enable-deprecated-ports = yes 配置项将消除该错误并继续。

$ bash ./configure --enable-deprecated-ports=yes
...
checking compilation type... native
configure: WARNING: The Solaris and SPARC ports are deprecated and may be removed in a future release.
...
Build performance summary:
* Cores to use:   32
* Memory limit:   96601 MB

为Solaris和SPARC(包括Solaris / SPARC,Solaris / x64,Linux / SPARC)配置构建时,将发出错误/警告。

Remove the Concurrent Mark Sweep (CMS) Garbage Collector

移除了CMS垃圾收集器。此更新将停用CMS编译,从源树中删除gc / cms目录的内容,并删除仅CMS选项。如果在JDK14中使用-XX:+UseConcMarkSweepGC的话,会出现警告,但是不会退出而是以默认的垃圾收集器运行。

ZGC on macOS (experimental)

之前的ZGC只能在linux上使用,现在mac上也能使用了。

ZGC on Windows (experimental)

之前的ZGC只能在linux上使用,现在windows(不能低于1803版本)上也能使用。

Deprecate the ParallelScavenge + SerialOld GC Combination

废弃了parallel young generation GC与SerialOld GC的组合( -XX:+UseParallelGC与-XX:-UseParallelOldGC配合开启),现在使用-XX:+UseParallelGC -XX:-UseParallelOldGC或者-XX:-UseParallelOldGC都会出现告警。

Remove the Pack200 Tools and API

移除了Pack200 API。

Text Blocks (Second Preview)

在Java中,要将HTML,XML,SQL或JSON代码片段嵌入到代码中通常很难阅读且难以保留,并且为了克服此问题,Java 14引入了Text Block。
JDK13引入的text blocks进行第二轮预览,JDK14的版本主要增加了两个escape sequences,分别是 与\s escape sequence。

由三个英文双引号(""")开始/结束。与字符串文字中的字符不同,内容可以直接包含双引号字符。 允许在文本块中使用\“,但不是必需的或不建议使用。"""可以使字符可以不转义出现,并且还可以从视觉上区分文本块和字符串文字。

//HTML without text block
String html = "\n" +
        "    \n" +
        "        

Hello, world

\n"
+ " \n" + "\n"; //HTML with text block String htmlTextBlock = """ <html> <body> <p>Hello, world</p> </body> </html> """;

Foreign-Memory Access API (Incubator)

提供了孵化版本的API用于操纵堆外内存。

你可能感兴趣的:(Java)