Java13新特性描述
2019年9月17日正式发布。本次发布的内容主要ZGC增加、更新Socket实现、Switch表达式更新等方面的改动。
动态应用程序类-数据共享
在Java10中对Java10中引入的应用程序类数据共享进一步的简化、改进和扩展,允许在Java应用程序执行结束时动态进行类归档,具体能被归档的类包括:所有已被加载、但不属于默认基层CDS的应用程序类和引用类库中的类。简单快捷使用cds存档操作。
增强ZGC释放未使用内存
ZGC是Java11引入的最为瞩目的垃圾回收特性,是一种可压缩、低延迟的垃圾收集器,不过在Java11中是实验性的引入,主要用来改善GC停顿时间,并支持几百MB至几个TB级别大小的堆,并且应用吞吐能力下降不会超过15%。目前只支持Linux/x64平台。
Java13对ZGC的改进,主要体现在下面几点
释放未使用内存给操作系统
支持最大堆大小未16TB
添加参数-XX:SoftMaxHeapSize 来软限制堆的大小
软限制堆大小指的是GC应努力是堆大小不要超过指定大小,但是如果实际需要也还是允许GC将堆大小增加到超过SoftMaxHeapSize指定值。如果你想降低堆的占用空间,还想保持临时弹性能力,保持内存的正常运行,不要把 SoftMaxHeapSize设置大于最大堆大小的值。
Java13中,ZGC内存释放功能,默认情况下是开启的,不过可以使用参数:-XX:-ZUncommit 现实关闭,同时如果将最小堆大小配置未等于最大堆大小,则将隐式禁用
延迟释放可以采用参数-XX:ZUncommitDelay = <seconds>控制 默认seconds==300秒。
Socket API重构
Java中的Socket API已经存在了二十多年了,Java13 为Socket API带来了新的底层实现方法,并且在Java13中是默认使用新的Socket实现,使其易于发现并在排除问题同时增加可维护性。Java13之前使用PlainSocketImpl 作为SocketImpl的具体实现。Java13中的新底层实现,引入NioSocketImpl的实现用以替换SocketImpl的PlainSocketImpl实现。为了最小化在重新实现已使用二十多年的方法时出现问题风险,在引入风险的同时,之前版本的实现未被移除。可以通过使用下列属性 以重新使用实现原方法:
-Djdk.net.usePlainSocketImpl = true
注:SocketImpl是一种传统的SPI机制,同时也是一个抽象类,并未制定具体的实现。在使用新实现时,有些情况可能会失败:
- 老本笨重PlainSocketImpl中的getInputStream()和getOutPutStream()方法返回的InputStream和OutputStream分别来自于其对应的扩展类型FileInputStream和FileOutputStream
- 使用自定义或其他平台的SocketImpl的服务器套接字无法使用其他类型SocketImpl返回Sockets的连接。
Switch表达式扩展(预览功能)
在Java12中引入了Switch表达式作为预览特性,在Java13中对Switch表达式做了增强改进,在块中引入了yield语句来返回值,而不是使用break。这意味着,Switch表达式返回值应该使用yield,而Switch应该使用break。在Java12之前的switch语法如下
- Java12之前
private static String hello(int number) { String result = ""; switch (number) { case 1, 2: result = "one or two"; break; case 3: result = "three"; break; case 4, 5, 6: result = "four or five or six"; break; default: result = "unknown"; break; }; return result; }
- Java12 改进
private static String hello(int number) { String result = switch (number) { case 1, 2 -> "one or two"; case 3 -> "three"; case 4, 5, 6 -> "four or five or six"; default -> "unknown"; }; return result; }
- Java13
public static String hello(int day) { return switch (day) { case 1: { yield "zhangsan"; } case 2: yield "lisi"; default: throw new IllegalStateException("Unexpected value: " + day); }; }
文本块(预览功能)
一直以来,Java语言在定义字符串的方式是有限的,字符串需要双引号开头,以双引号结尾,这导致字符串不能够多行使用,需要转义符转移或者换行连接支持多行 但这样会增加编辑工作量。
Java3引入了文本块来解决多行文本的问题,文本块以三重双引号开头,并以同样的三重引号结尾终止
String str= """ A B C Linux """;
对于Java13的预览 我们需要意识到预览功能不是beta形式。由于预览还不是规范的一部分,因此有必要编译喝运行时进行明确 。采用参数
$ javac --enable-preview --release 13 HelloWorld.java $ java --enable-preview Example
网友评论