Java 13 明天发布,最新最全新特性解读
2017年8月,JCP执行委员会提出将Java的发布频率改为每六个月一次,新的发布周期严格遵循时间点,将在每年的3月份和9月份发布。
目前,JDK官网上已经可以看到JDK 13的进展,最新版的JDK 13将于2019年9月17日发布。
目前,JDK13处于Release-Candidate Phase(发布候选阶段),将于9月17日正式发布。目前该版本包含的特性已经全部固定,主要包含以下五个:
JEP 350,Dynamic CDS Archives
JEP 351,ZGC: Uncommit Unused Memory
JEP 353,Reimplement the Legacy Socket API
JEP 354: Switch Expressions (Preview)
JEP 355,Text Blocks (Preview)
下面来逐一介绍下这五个重要的特性。
Dynamic CDS Archives
这一特性是在JEP310:Application Class-Data Sharing基础上扩展而来的,Dynamic CDS Archives中的CDS指的就是Class-Data Sharing。
那么,这个JEP310是个啥东西呢?
我们知道在同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机都单独装载自己需要的所有类,启动成本和内存占用是比较高的。所以Java团队引入了CDS的概念,通过把一些核心类在每个JVM间共享,每个JVM只需要装载自己的应用类,启动时间减少了,另外核心类是共享的,所以JVM的内存占用也减少了。
CDS 只能作用于 Boot Class Loader 加载的类,不能作用于 App Class Loader 或者自定义的 Class Loader 加载的类。
在 Java 10 中,则将 CDS 扩展为 AppCDS,顾名思义,AppCDS 不止能够作用于 Boot Class Loader了,App Class Loader 和自定义的 Class Loader 也都能够起作用,大大加大了 CDS 的适用范围。也就说开发自定义的类也可以装载给多个JVM共享了。
Java 10中包含的JEP310的通过跨不同Java进程共享公共类元数据来减少了内存占用和改进了启动时间。
但是,JEP310中,使用AppCDS的过程还是比较复杂的,需要有三个步骤:
1、决定要 Dump 哪些 Class
2、将类的内存 Dump 到归档文件中
3、使用 Dump 出来的归档文件加快应用启动速度
这一次的JDK 13中的JEP 350 ,在JEP310的基础上,又做了一些扩展。允许在Java应用程序执行结束时动态归档类,归档类将包括默认的基础层 CDS(class data-sharing)存档中不存在的所有已加载的应用程序类和库类。
也就是说,在Java 13中再使用AppCDS的时候,就不在需要这么复杂了。
ZGC: Uncommit Unused Memory
在讨论这个问题之前,想先问一个问题,JVM的GC释放的内存会还给操作系统吗?
GC后的内存如何处置,其实是取决于不同的垃圾回收器的。因为把内存还给OS,意味着要调整JVM的堆大小,这个过程是比较耗费资源的。
在JDK 11中,Java引入了ZGC,这是一款可伸缩的低延迟垃圾收集器,但是当时只是实验性的。并且,ZGC释放的内存是不会还给操作系统的。
而在Java 13中,JEP 351再次对ZGC做了增强,本次 ZGC 可以将未使用的堆内存返回给操作系统。之所以引入这个特性,是因为如今有很多场景中内存是比较昂贵的资源,在以下情况中,将内存还给操作系统还是很有必要的:
- 1、那些需要根据使用量付费的容器
- 2、应用程序可能长时间处于空闲状态并与许多其他应用程序共享或竞争资源的环境。
- 3、应用程序在执行期间可能有非常不同的堆空间需求。例如,启动期间所需的堆可能大于稍后在稳定状态执行期间所需的堆。
Reimplement the Legacy Socket API
使用易于维护和调试的更简单、更现代的实现替换 java.net.Socket 和 java.net.ServerSocket API。
java.net.Socket和java.net.ServerSocket的实现非常古老,这个JEP为它们引入了一个现代的实现。现代实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来使用它们。
运行一个实例化Socket和ServerSocket的类将显示这个调试输出。这是默认的(新的):
java -XX:+TraceClassLoading JEP353 | grep Socket
[0.033s][info ][class,load] java.net.Socket source: jrt:/java.base
[0.035s][info ][class,load] java.net.SocketOptions source: jrt:/java.base
[0.035s][info ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.039s][info ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800b50840 source: java.net.SocketImpl
[0.042s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
[0.042s][info ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base
[0.043s][info ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base
[0.044s][info ][class,load] java.net.DelegatingSocketImpl source: jrt:/java.base
[0.044s][info ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
[0.044s][info ][class,load] java.net.ServerSocket source: jrt:/java.base
[0.045s][info ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base
[0.045s][info ][class,load] java.net.ServerSocket$1 source: jrt:/java.base
上面输出的sun.nio.ch.NioSocketImpl就是新提供的实现。
如果使用旧的实现也是可以的(指定参数jdk.net.usePlainSocketImpl):
$ java -Djdk.net.usePlainSocketImpl -XX:+TraceClassLoading JEP353 | grep Socket
[0.037s][info ][class,load] java.net.Socket source: jrt:/java.base
[0.039s][info ][class,load] java.net.SocketOptions source: jrt:/java.base
[0.039s][info ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.043s][info ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800b50840 source: java.net.SocketImpl
[0.046s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
[0.047s][info ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base
[0.047s][info ][class,load] java.net.PlainSocketImpl source: jrt:/java.base
[0.047s][info ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:/java.base
[0.047s][info ][class,load] sun.net.ext.ExtendedSocketOptions source: jrt:/java.base
[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions source: jrt:/jdk.net
[0.047s][info ][class,load] java.net.SocketOption source: jrt:/java.base
[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:/jdk.net
[0.047s][info ][class,load] jdk.net.SocketFlow source: jrt:/jdk.net
[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions source: jrt:/jdk.net
[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:/jdk.net
[0.048s][info ][class,load] jdk.net.LinuxSocketOptions source: jrt:/jdk.net
[0.048s][info ][class,load] jdk.net.LinuxSocketOptions$$Lambda$2/0x0000000800b51040 source: jdk.net.LinuxSocketOptions
[0.049s][info ][class,load] jdk.net.ExtendedSocketOptions$1 source: jrt:/jdk.net
[0.049s][info ][class,load] java.net.StandardSocketOptions source: jrt:/java.base
[0.049s][info ][class,load] java.net.StandardSocketOptions$StdSocketOption source: jrt:/java.base
[0.051s][info ][class,load] sun.net.ext.ExtendedSocketOptions$$Lambda$3/0x0000000800b51440 source: sun.net.ext.ExtendedSocketOptions
[0.057s][info ][class,load] java.net.DelegatingSocketImpl source: jrt:/java.base
[0.057s][info ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
[0.058s][info ][class,load] java.net.ServerSocket source: jrt:/java.base
[0.058s][info ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base
[0.058s][info ][class,load] java.net.ServerSocket$1 source: jrt:/java.base
上面的结果中,旧的实现java.net.PlainSocketImpl被用到了。
Switch Expressions (Preview)
在JDK 12中引入了Switch表达式作为预览特性。JEP 354修改了这个特性,它引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield, switch语句(不返回值)应该使用break。
在以前,我们想要在switch中返回内容,还是比较麻烦的,一般语法如下:
int i;
switch (x) {
case "1":
i=1;
break;
case "2":
i=2;
break;
default:
i = x.length();
break;
}
在JDK13中使用以下语法:
int i = switch (x) {
case "1" -> 1;
case "2" -> 2;
default -> {
int len = args[1].length();
yield len;
}
};
或者
int i = switch (x) {
case "1": yield 1;
case "2": yield 2;
default: {
int len = args[1].length();
yield len;
}
};
在这之后,switch中就多了一个关键字用于跳出switch块了,那就是yield,他用于返回一个值。和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。
Text Blocks (Preview)
在JDK 12中引入了Raw String Literals特性,但在发布之前就放弃了。这个JEP在引入多行字符串文字(text block)在意义上是类似的。
text block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。
我们以前从外部copy一段文本串到Java中,会被自动转义,如有一段以下字符串:
<html>
<body>
<p>Hello, world</p>
</body>
</html>
将其复制到Java的字符串中,会展示成以下内容:
"<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
即被自动进行了转义,这样的字符串看起来不是很直观,在JDK 13中,就可以使用以下语法了:
"""
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
使用“”“作为文本块的开始符合结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。
如常见的SQL语句:
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
看起来就比较直观,清爽了。
总结
以上,就是JDK13中包含的5个特性,能够改变开发者的编码风格的主要有Text Blocks和Switch Expressions两个新特性,但是这两个特性还处于预览阶段。
而且,JDK13并不是LTS(长期支持)版本,如果你正在使用Java 8(LTS)或者Java 11(LTS),暂时可以不必升级到Java 13.
参考资料: https://openjdk.java.net/projects/jdk/13/ https://metebalci.com/blog/what-is-new-in-java-13/ https://www.jianshu.com/p/890196bf529a
Java 13 明天发布,最新最全新特性解读的更多相关文章
- Java 13 即将发布,新特性必须抢先看!
作者:h4cd 本文转载自开源中国(ID:oschina2013) 由于 Java 现在采取"半年发布一次新版本"的模式,所以 Java 12 的下一个版本 Java 13/JDK ...
- 2019年9月17 发布 Java 13
Java 13 明天发布,最新最全新特性解读 2017年8月,JCP执行委员会提出将Java的发布频率改为每六个月一次,新的发布周期严格遵循时间点,将在每年的3月份和9月份发布. 目前,JDK官网 ...
- Java 9 ← 2017,2019 Java → 13 ,都发生了什么?
距离 2019 年结束,只剩下 35 天了.你做好准备迎接 2020 年了吗? 一到年底,人就特别容易陷入回忆和比较之中,比如说这几天, 的对比挑战就火了! 这个话题登上了微博的热搜榜,也刷爆了朋友圈 ...
- Java 9 ← 2017,2019 → Java 13,来看看Java两年来的变化
距离 2019 年结束,只剩下 33 天了.你做好准备迎接 2020 年了吗? 一到年底,人就特别容易陷入回忆和比较之中,比如说这几天的对比挑战就火了! 这个话题登上了微博的热搜榜,也刷爆了朋友圈, ...
- Java 13 特性解读
Java 13 特性解读 转 https://blog.csdn.net/bjweimengshu/article/details/100978383 2017年8月,JCP执行委员会提出将 ...
- Java 13 发布了!
点击上方蓝色链接,关注并"设为星标" Java干货,每天及时推送 通告一下,Java 13 09/17 发布了,尝鲜地址: https://www.oracle.com/techn ...
- Java 17 将要发布,补一下 Java 13 中的新功能
本文章属于Java 新特性教程 系列,已经收录在 Github.com/niumoo/JavaNotes ,点个赞,不迷路. 自从 Oracle 调整了 Java 的版本发布节奏之后,Java 版本发 ...
- Java 13新特性
switch表达式 switch表达式是Java 12开始就提供的预览特性,到了Java 13仍然没有被转正.此特性可以把switch的执行结果组合到复合表达式中进行运算. import java.t ...
- JDK 16 正式发布,一次性发布 17 个新特性…不服不行!
上一篇:Java 15 正式发布, 14 个新特性 JDK 16 正式发布 牛逼啊,JDK 15 刚发布半年(2020/09/15),JDK 16 又如期而至(2021/03/16),老铁们,跟上. ...
随机推荐
- 心里想的VS嘴上说的
心里想的VS嘴上说的 背景:昨天开会,在招行总行那边,今天检讨下自己不会说话,真是太难了我! 一.昨日重现 现在回想起当时的场景觉得自己也真是搞笑,这都没死,太难了我.昨天下午在五楼开会,这也是我入职 ...
- XML学习(一)
本文主要记录xml学习过程中的一些笔记,包括xml作用,语法以及解析. 1.HTML和XML的区别 1.1.HTML 名称: HyperText Markup Languae(超文本标记语言) ...
- java之异常详解
一.什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域正常运行的情况,称之为异常. 二.异常体系 Java把异常当作对象来处理,并定义一个基类java. ...
- UI 组件 | Toggle
Toggle(复选框)组件 Toggle 是一个 CheckBox,当它和 ToggleGroup 一起使用的时候,可以变成 RadioButton. 创建 Toggle 组件 层级管理器右击-> ...
- Windows Server 2008磁盘管理
下面学习一下磁盘管理,基本磁盘 分区 空间只能是同一块磁盘的空间,动态磁盘 卷 空间可以是多块硬盘上的空间,怎么创建 RAID-0 条带卷 读写快 无容错 适合存放不太重要的数据 ,RAID-1 ...
- 写个shell脚本搭载jenkins让你的程序部署飞起来
[转载请注明]: 原文出处:https://www.cnblogs.com/jstarseven/p/11399251.html 作者:jstarseven 码字挺辛苦的..... 说明 ...
- Go组件学习——database/sql数据库连接池你用对了吗
1.案例 case1: maxOpenConns > 1 func fewConns() { db, _ := db.Open("mysql", "root:roo ...
- 微服务SpringCloud之Spring Cloud Config配置中心服务化
在前面两篇Spring Cloud Config配置中心的博客中都是需要指定配置服务的地址url:spring.cloud.config.uri,客户端都是直接调用配置中心的server端来获取配置文 ...
- 大转盘(CocosCreator)
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 1.在场景中搭建大转盘场景,假设 奖项有n项,对应的每项旋转角度如下: 第几项 需要旋转的角度 0 360/n/2 1 360/ ...
- codeforces 755D. PolandBall and Polygon(线段树+思维)
题目链接:http://codeforces.com/contest/755/problem/D 题意:一个n边形,从1号点开始,每次走到x+k的位置如果x+k>n则到x+k-n的位置,问每次留 ...