原创|java13明天发布,最新最全新特性解读

     2022-04-03     727

关键词:

原创 | Java 13 明天发布,最新最全新特性解读

△Hollis, 一个对Coding有着独特追求的人△
技术图片
这是Hollis的第 229篇原创分享

作者 l Hollis
来源 l Hollis(ID:hollischuang)

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)
下面来逐一介绍下这五个重要的特性。

1、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的时候,就不在需要这么复杂了。

2、ZGC: Uncommit Unused Memory

在讨论这个问题之前,想先问一个问题,JVM的GC释放的内存会还给操作系统吗?

GC后的内存如何处置,其实是取决于不同的垃圾回收器的。因为把内存还给OS,意味着要调整JVM的堆大小,这个过程是比较耗费资源的。

在JDK 11中,Java引入了ZGC,这是一款可伸缩的低延迟垃圾收集器,但是当时只是实验性的。并且,ZGC释放的内存是不会还给操作系统的。
技术图片

而在Java 13中,JEP 351再次对ZGC做了增强,本次 ZGC 可以将未使用的堆内存返回给操作系统。之所以引入这个特性,是因为如今有很多场景中内存是比较昂贵的资源,在以下情况中,将内存还给操作系统还是很有必要的:

  • 1、那些需要根据使用量付费的容器
  • 2、应用程序可能长时间处于空闲状态并与许多其他应用程序共享或竞争资源的环境。
  • 3、应用程序在执行期间可能有非常不同的堆空间需求。例如,启动期间所需的堆可能大于稍后在稳定状态执行期间所需的堆。

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被用到了。

4、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块。

5、Text Blocks (Preview)

在JDK 12中引入了Raw String Literals特性,但在发布之前就放弃了。这个JEP在引入多行字符串文字(text block)在意义上是类似的。
text block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。
我们以前从外部copy一段文本串到Java中,会被自动转义,如有一段以下字符串:

<html>
  <body>
      <p>Hello, Hollis</p>
  </body>
</html>

将其复制到Java的字符串中,会展示成以下内容:

"<html>
" +
"    <body>
" +
"        <p>Hello, Hollis</p>
" +
"    </body>
" +
"</html>
";

即被自动进行了转义,这样的字符串看起来不是很直观,在JDK 13中,就可以使用以下语法了:

"""
<html>
  <body>
      <p>Hello, Hollis</p>
  </body>
</html>
""";

使用"""作为文本块的开始符合结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。
如常见的SQL语句:

String query = """
    SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
    WHERE `CITY` = ‘INDIANAPOLIS‘
    ORDER BY `EMP_ID`, `LAST_NAME`;
""";

看起来就比较直观,清爽了。

6、总结

以上,就是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工程师成神之路系列文章
在 GitHub 更新中,欢迎关注,欢迎star。
技术图片
直面Java第262期:volatile是如何解决有序性问题的?
深入并发第009期:到底什么是Java内存模型?

  • MORE | 更多精彩文章 -
  • 别再用Else语句写代码了!
  • 如何辨别二逼互联网公司!?
  • 让你的 IDEA 好用到飞起来的配置
  • 程序员利用网吧挖矿,获利上亿元~!

如果你喜欢本文,
请长按二维码,关注 Hollis.
技术图片
转发至朋友圈,是对我最大的支持。
好文章,我在看??

个推解读android13新特性,发布《android13适配指南》(代码片段)

...上传到Android开源项目(AOSP)中,Android13正式发布。自从2022年2月Android13第一个预览版上线以来,历经7个月的测试和优化,正式版本的Android13终于来了!Android13仍然聚焦个人隐私保护和安全ÿ 查看详情

个推解读android13新特性,发布《android13适配指南》(代码片段)

...上传到Android开源项目(AOSP)中,Android13正式发布。自从2022年2月Android13第一个预览版上线以来,历经7个月的测试和优化,正式版本的Android13终于来了!Android13仍然聚焦个人隐私保护和安全ÿ 查看详情

java14新特性

Java14上个月发布了,官方解读:https://openjdk.java.net/projects/jdk/14/先中文翻译一下:  下面验证一下Java14"真香定律"~ 一、准备工作安装JDK14;IDEA最新版的(2020.1版以后的,旧版可能不支持,其他编辑器没试过)二、新特性 ①P... 查看详情

rancherv2.6.4社区版新特性解读

SUSERancher发布了最新的Rancherv2.6.4版本,除了新特性之外,还处理了数百个issue,以及各种如Docker和Kubernetes等生态更新的兼容验证工作。与此同时,Rancherv2.4.18作为v2.4系列的终结版也进行了发布,此版本没有特... 查看详情

全网最全的php8新特性(代码片段)

...却还不多,虽然功能新增了很多,但是因为作为最新版本的php,是不可能直接应用到项目中的,只有经过真操实弹的项目检测,才会慢慢推广迭代,但是作为最新版本的php8,它的新特性我们还是必 查看详情

原创:史上对bm25模型最全面最深刻的解读以及lucene排序深入讲解(佟学强)

垂直搜索结果的优化包括对搜索结果的控制和排序优化两方面,其中排序又是重中之重。本文将全面深入探讨垂直搜索的排序模型的演化过程,最后推导出BM25模型的排序。然后将演示如何修改lucene的排序源代码,下一篇将深入... 查看详情

java最强最新知识体系总结(2021版)

一、Java基础知识1、基础知识分类内容链接Java基础【Java知识点详解1】缓存链接1Java基础【Java知识点详解2】动态代理链接2Java基础【Java知识点详解3】序列化与反序列化链接3Java基础【Java知识点详解4】泛型链接4Java基础【Java知识... 查看详情

java先驱者发布最新java全栈面试“秘籍”,助力你吃透java新特性!

这个是大概的目录内容这份Java高级全栈的面试题内容很多,面试题(含答案)的质量肯定是一点问题都没有的,但就是有一个很大的缺点,就是内容太多了!!!老师十分想给大家全部截图展示出... 查看详情

最全的swift4新特性解析

转自:http://www.jianshu.com/p/f35514ae9c1aWWDC2017带来了很多惊喜。Swift4也伴随着Xcode9测试版来到了我们的面前,很多强大的新特性非常值得我们期待在正式项目中去使用它。因为Swift4是开源的,如果你关注swift-evolution这个项目的话,就... 查看详情

springboot2:springboot2.0新特性

...于Spring,而SpringCloud又依赖于SpringBoot,因此SpringBoot2.0的发布正式整合了Spring5.0的很多特性,同样后面SpringCloud最新版本的发布也需要整合最新的SpringBoot2.0内容。一、新版本特性1,基于Java8,支持Java9也就是说SpringBoot 查看详情

springboot3.0正式发布及新特性解读(代码片段)

SpringBoot3.0正式发布同时发布更新的还有2.7.x和2.6.x两条版本线,SpringBoot是我见过的发版最守时的技术框架之一。SpringBoot3.0现已正式发布,它包含了12个月以来151个开发者的5700多次代码提交。这是自4.5年前发布2.0以来,... 查看详情

可能是国内第一篇全面解读java现状及趋势的文章

作者|张晓楠DragonwellJDK?最新版本8.1.1-GA发布,包括全新特性和更新!导读:InfoQ发布《2019中国Java发展趋势报告》,反映Java在中国发展的独特性,同时也希望大家对Java有一个正确的认识。2个月前,InfoQ英文站发布了一份《2019Java... 查看详情

pg11新特性解读:新增非空默认值字段不需要重写表-原理

本文对原理进行解读 查看详情

atititspring3.03.13.24.04.35.0新特性

Atititspring3.03.13.24.04.35.0新特性         Spring3.0的新特性及其分析-我的人生不甘于平庸!-ITeye技术网站.htmlSpring3.0带来的新特性-未来之路-博客频道-CSDN.NET.htmlSpring3.1新特性一览表-开源中国社区.htmlSp... 查看详情

java14令人期待的5大新特性,打包工具终于要来了(代码片段)

随着新的Java发布生命周期的到来,新版本预计将于2020年3月发布,本文将对其中的5个主要特性作些概述。Java13刚刚发布给开发人员使用不久,最新版本的JDK于2019年9月发布。但是很少有公司现在改用了Java13,因为这个版本看起来... 查看详情

java9新特性之——jshell

 java9已经在北京时间9月22日正式发布,开发者可以在oraclejdk官网上下载到最新的jdk9。jdk9和jdk8中的新特性不同:jdk8中的stream和lambda表达式能够让开发者非常快速和直观地感受到新版本的功能特性,而java9中的关键更新——模... 查看详情

jdk11新特性——概述

...k11概述北京时间2018年9月26日,Oracle官方宣布Java11正式发布。这是Java大版本周期变化后的第一个长期支持版本,非常值得关注。从官网即可下载,最新发布的Java11将带来ZGC、HttpClient等重要特性,一共包含17个JEP(JDKE... 查看详情

openkruisev0.10.0新特性workloadspread解读

...1a;针对需求,OpenKruise在v0.10.0版本中新增了WorkloadSpread特性。目前它支持配合Deployment、ReplicaSet、CloneSet这些workload,来管理它们下属Pod的分区部署与弹性伸缩。下文会深入介绍WorkloadSpread的应用场景和实现原理,帮助用... 查看详情