Hello World

吞风吻雨葬落日 欺山赶海踏雪径

0%

Java 13 新特性

jdk 13 主要的新特性参考:
openjdk JDK 13

baeldung New Features in Java 13

JDK 13 的新特性

2019年9月,Java 13发布了(每六个月发布一次),看下发布的新特性(这次加的不多):

预览版本的开发特性

感觉也就两个预览特性比较重要的了。注意,都是预览版特性,需要在命令行中添加 –enable-preview 参数来启用预览版特性。

Switch Expressions (JEP 354)

在 Java 12 中加入的预览版 switch 表达式又更新了,这次加了 yield 语句。 yield 可以直接在 switch 表达式中返回一个值(复杂表达式中用{}包含后需要返回值)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
@SuppressWarnings("preview")
public void whenSwitchingOnOperationSquareMe_thenWillReturnSquare() {
var me = 4;
var operation = "squareMe";
var result = switch (operation) {
case "doubleMe" -> {
yield me * 2;
}
case "squareMe" -> {
yield me * me;
}
default -> me;
};

assertEquals(16, result);
}

我们可以更简单的使用 switch 来实现策略匹配。

注意: 当前依旧是预览版的特性

Text Blocks (JEP 355)

Java 终于支持多行文本块了。

以前

1
2
String JSON_STRING 
= "{\r\n" + "\"name\" : \"Baeldung\",\r\n" + "\"website\" : \"https://www.%s.com/\"\r\n" + "}";

现在直接用文本块来实现:

1
2
3
4
5
6
String TEXT_BLOCK_JSON = """
{
"name" : "Baeldung",
"website" : "https://www.%s.com/"
}
""";

有了这个特性,JSON XML HTML 等都更容易读写和维护了。 String 的各个方法都支持这类字符串。

1
2
3
4
5
6
@Test
public void whenTextBlocks_thenStringOperationsWorkSame() {
assertThat(TEXT_BLOCK_JSON.contains("Baeldung")).isTrue();
assertThat(TEXT_BLOCK_JSON.indexOf("www")).isGreaterThan(0);
assertThat(TEXT_BLOCK_JSON.length()).isGreaterThan(0);
}

同时,java.lang.String也加入了三个方法来管理文本块:

  • stripIndent() 模拟编译器以删除附带的空白
  • translateEscapes() 将转义序列 (如“\t”转换为“\t”)
  • formatted() 文本块的 String::format 方法

因为文本块是预览特性,可能在未来的版本中删除,所以这些方法是被标记为 deprecation

Dynamic CDS Archives (JEP 350)

Class data sharing (CDS) 成为 HotSpot VM 重要特性已经有一段时间了,它允许在不同JVM之间共享类元数据,以减少启动时间和内存占用。
JDK 10 扩展了 CDS 的能力,允许在应用之间CDS(AppCDS),让开发者有了控制应用类加入共享归档的能力,JDK 12 增强了这个特性,默认就使用 CDS 。

当时归档应用的class有点麻烦。为了生成归档文件,开发人员必须先对其应用程序进行试运行以创建类列表,然后将其转储到归档中。之后,这个归档才可以用于在JVM之间共享元数据。
通过 dynamic archiving JDK 13 简化了这个过程,现在我们可以在程序退出的时候在生成类的共享归档,就不必要试运行了。

我们可以添加 -XX:ArchiveClassesAtExit 参数来启用退出执行动态归档,同时我们需要设定归档文件的名称。

1
java -XX:ArchiveClassesAtExit=<archive filename> -cp <app jar> AppName

下次这个应用启动的时候把命令替换为 -XX:SharedArchiveFile来使用归档。

1
java -XX:SharedArchiveFile=<archive filename> -cp <app jar> AppName

ZGC: Uncommit Unused Memory (JEP 351)

ZGC 作为一个低延迟(GC暂停时间不会超过10ms)的垃圾回收器在Java 11中被引入。然而不像其他的 HotSpot VM的GC, 比如 G1 或者 Shenandoah ,ZGC 没有能力归还不再使用的堆内存。
Java 13 中终于实现了ZGC这个能力。当前我们可以减少内存占用来实现性能的提升。

在 Java 13 中, ZGC 释放不用的内存给操作系统直到达到了最小的堆大小 的这个特性是默认的,如果要回到像 Java 11 的样子,需要

  • 加上 -XX:-ZUncommit 参数
  • 把最小堆大小(-Xms) 设置成与最大堆大小(-Xmx)一样大
    另外,ZGC 支持的最大堆大小已经从 4TB 升级到了 16TB

Reimplement the Legacy Socket API (JEP 353)

Socket API (java.net.Socketjava.net.ServerSocket) 在Java 诞生依赖就一直是一个重要的组成部分。但是在过去的20年中他一直都是这么老久,已经很难维护了。
Java 13 中用现代化的用户模式线程替换了其底层实现,PlainSocketImpl被替换成了 NioSocketImpl,这个新编码的实现基于与java.nio相同的内部架构。

当然,我们是可以退回到 PlainSocketImpl的,在 JVM 参数中加入 -Djdk.net.usePlainSocketImpl 来实现回退,现在用的是NioSocketImpl了。

其他的变化

FileSystems.newFileSystem

java.nio.file.FileSystems 添加了三个新方法,以便更好的使用 FileSystem

  • newFileSystem(Path)
  • newFileSystem(Path, Map<String, ?>)
  • newFileSystem(Path, Map<String, ?>, ClassLoader)

java.nio.ByteBuffer

java.nio.ByteBuffer 新增加方法 get(byte[] dst) 方法可将 ByteBuffer 的内容传输到指定的数组中,方法 put(byte[] src) 用于将指定字节数组中的内容全部传输到 ByteBuffer 中(批量)。

Unicode 12.1

下面的相关 API 做了对 unicode 12.1 版本的支持:

  • java.lang.Character
  • java.text.Bidi 和 java.text.Normalizer
  • java.util.regex 包

Javadoc

不再支持使用 html4 生成 api 文档,jdk9 开始就支持了 html5,生成 api 文档时要保证使用的 html 标签必须能完全符合 html5。
不再支持一些老的 javadoc API,包含 com.sun.javadoc , 旧的文档部件 (com.sun.tools.doclets.standard), 和旧的入口 (com.sun.tools.javadoc.Start)等。

杂七杂八(misc)

  • 删除系统属性 awt.toolkit
  • 删除命令行参数 -XX+AggressiveOpts
  • SunJSSE 中删除了对RSA KeyFactory,RSA KeyPairGenerator,MD2withRSA,MD5withRSA, 和SHA1withRSA Signature的支持
  • 删除两个 DocuSign 根证书:certplusclass2primaryca、certplusclass3pprimaryca
  • 删除两个Comodo根证书:utnuserfirstclientauthemailca、utnuserfirsthardwareca
  • 内部包 com.sun.net.ssl 被删除
  • javax.security.cert api 被废弃
  • 废弃java 命令行参数 -Xverifynone 和 -noverify
  • 等等

参考

JDK 13

New Features in Java 13

Java13新特性及代码示例

还在用JDK6的同学,来看看JDK13新特性详解吧

java 13 引入文本块,对 switch 语法做了增强