文章目录
- JAVA13概述
- 语法层面特性
- switch表达式(预览)
- 文本块(预览)
- API层次特性
- 重新实现旧版套接字API
- 其他变化
- ZGC取消未使用的内存
- 增加废弃和移除
- 增加项
- 移除项
- 废弃项
JAVA13概述
2019年9月17日,国际知名的OpenJDK开源社区发布了Java编程语言环境的最新版本OpenJDK13。
Features:总共有5个新的JEP(JDK Enhancement Proposals):
http://openjdk.java.net/projects/jdk/13/
Features:
350:Dynamic CDS Archives:动态CDS档案
351:ZGC: Uncommit Unused Memory:ZGC:取消使用未使用的内存
353:Reimplement the Legacy Socket API:重新实现旧版套接字API
354:Switch Expressions (Preview):switch表达式(预览)
355:Text Blocks (Preview):文本块
语法层面特性
switch表达式(预览)
在JDK 12中引入了switch表达式作为预览特性。JDK 13提出了第二个switch表达式预览。JEP 354修改了这个特性,它引入了yield语句,用于返回值。
在以前,我们想要在switch中返回内容,还是比较麻烦的,一般语法如下:
String x = "3";
int i;
switch (x) {case "1":i=1;break;case "2":i=2;break;default:i = x.length();break;
}
System.out.println(i);
在JDK13中使用以下语法:
String x = "3";
int i = switch (x) {case "1" -> 1;case "2" -> 2;default -> {yield 3;}
};
System.out.println(i);
或者:
String x = "3";
int i = switch (x) {case "1":yield 1;case "2":yield 2;default:yield 3;
};
System.out.println(i);
在这之后,switch中就多了一个关键字用于跳出switch块了,那就是yield,他用于返回一个值。和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。
文本块(预览)
在Java中,通常需要使用String类型表达HTML,XML,SQL或JSON等格式的字符串,在进行字符串赋值时需要进行转义和连接操作,然后才能编译该代码,这种表达方式难以阅读并且难以维护。文本块就是指多行字符串,例如一段格式化后的xml、json等。而有了文本块以后,用户不需要转义,Java能自动搞定。因此,文本块将提高Java程序的可读性和可写性。
定义一段HTML代码
<html><body><a href="http://www.xxx.com">xxx</a></body>
</html>
将这段代码放入java的String中,会出现如下效果
String words ="<html>\n" +"\t<body>\n" +"\t\t<a href=\"http://www.xxx.com\">xxx</a></a>\n" +"\t</body>\n" +"</html>";
自动将空格换行缩进和特殊符号进行了转义,但是在JDK13中可以使用这样的语法了:
String words = """<html><body><a href="http://www.mashibing.com">波波烤鸭</a></body></html>""";
使用"""作为文本块的开始符和结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。
如常见的SQL语句:
select empno,ename,sal,deptno
from emp
where deptno in (40,50,60)
order by deptno asc
原来的方式:
String query = "select empno,ename,sal,deptno\n" +
"from emp\n" +
"where deptno in (40,50,60)\n" +
"order by deptno asc";
现在方式:
String newQuery = """
select empno,ename,sal,deptno
from emp
where deptno in (40,50,60)
order by deptno asc
""";
以下是错误格式的文本块
String a = """"""; // 开始分隔符后没有行终止符
String b = """ """; // 开始分隔符后没有行终止符
String c = """
"; // 没有结束分隔符
String d = """
abc \ def
"""; // 含有未转义的反斜线(请参阅下面的转义处理)
在运行时,文本块将被实例化为String的实例,就像字符串一样。从文本块派生的String实例与从字符串派生的实例是无法区分的。具有相同内容的两个文本块将引用相同的String实例,就像字符串一样。
编译器在编译时,会删除多余的空格
下面这段代码中,我们用.
来表示我们代码中的的空格,而这些位置的空格就是多余的。
String html = """
..............<html>
.............. <body>
.............. <p>Hello, world</p>
.............. </body>
..............</html>
..............""";
这些多余的空格对于程序员来说是看不到的,但是他又是实际存在的,所以如果编译器不做处理,可能会导致程序员看到的两个文本块内容是一样的,但是这两个文本块却因为存在这种多余的空格而导致差异,比如哈希值不相等。
转义注意事项
使用 \n,\f 和\r 来进行字符串的垂直格式化,使用 \b和 \t进行水平格式化。比如下面的代码是合法的:
String html = """
<html>\n
<body>\n
<p>Hello, world</p>\n
</body>\n
</html>\n
""";
可以在任何可以使用字符串的地方使用文本块。例如,文本块和字符串可以相互连接:
String code = "public void print(Object o) {" +
"""
System.out.println(Objects.toString(o));
}
""";
API层次特性
重新实现旧版套接字API
全新实现的 NioSocketImpl 来替换JDK1.0的PlainSocketImpl。此实现与NIO实现共享相同的内部基础结构,并且与现有的缓冲区高速缓存机制集成在一起,因此不需要使用线程堆栈.除此之外,他还有一些其他更改,例如使用java.lang.ref.Cleaner机制关闭套接字,实现在尚未关闭的套接字上进行了垃圾收集,以及在轮训时套接字出于非阻塞模式时处理超时操作等方法
- 它便于维护和调试,与 NewI/O (NIO) 使用相同的 JDK 内部结构,因此不需要使用系统本地代码。
- 它与现有的缓冲区缓存机制集成在一起,这样就不需要为 I/O 使用线程栈。
- 它使用 java.util.concurrent 锁,而不是 synchronized 同步方法,增强了并发能力。
- 新的实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来切换到旧版本。
其他变化
ZGC取消未使用的内存
在Java 13中,JEP 351再次对ZGC做了增强,将没有使用的堆内存归还给操作系统。ZGC当前不能把内存归还给操作系统,即使是那些很久都没有使用的内存,也只进不出。这种行为并不是对任何应用和环境都是友好的,尤其是那些内存占用敏感的服务,例如:
- 按需付费使用的容器环境;
- 应用程序可能长时间闲置,并且和很多其他应用共享和竞争资源的环境;
- 应用程序在执行期间有非常不同的堆空间需求,例如,可能在启动的时候所需的堆比稳定运行的时候需要更多的堆内存。
增加废弃和移除
增加项
- 添加FileSystems.newFileSystem(Path, Map<String, ?>) Method
- 新的java.nio.ByteBuffer Bulk get/put Methods Transfer Bytes Without Regard to Buffer Position
- 支持Unicode 12.1
- 添加-XX:SoftMaxHeapSize Flag,目前仅仅对ZGC起作用
- ZGC的最大heap大小增大到16TB
移除项
- 移除awt.toolkit System Property
- 移除Runtime Trace Methods
- 移除-XX:+AggressiveOpts
- 移除Two Comodo Root CA Certificates、Two DocuSign Root CA Certificates
- 移除内部的com.sun.net.ssl包
废弃项
- 废弃-Xverify:none及-noverify
- 废弃rmic Tool并准备移除
- 废弃javax.security.cert并准备移除