1. 首页
  2. IT资讯

Java 13 新特性全面解读

“u003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRbiRsmjFrZY4rp” img_width=”640″ img_height=”100″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002FRQJuu1nHJV5Mc2″ img_width=”1023″ img_height=”682″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003E作者 l Hollisu003Cu002Fpu003Eu003Cpu003E本文经授权转载自Hollis(ID:hollischuang)u003Cu002Fpu003Eu003Cpu003E2017年8月,JCP执行委员会提出将Java的发布频率改为每六个月一次,新的发布周期严格遵循时间点,将在每年的3月份和9月份发布。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRch9qCH5qQOGGz” img_width=”613″ img_height=”543″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003E目前该版本包含的特性已经全部固定,主要包含以下五个:u003Cu002Fpu003Eu003Cpu003EJEP 350,Dynamic CDS Archivesu003Cu002Fpu003Eu003Cpu003EJEP 351,ZGC: Uncommit Unused Memoryu003Cu002Fpu003Eu003Cpu003EJEP 353,Reimplement the Legacy Socket APIu003Cu002Fpu003Eu003Cpu003EJEP 354: Switch Expressions (Preview)u003Cu002Fpu003Eu003Cpu003EJEP 355,Text Blocks (Preview)u003Cu002Fpu003Eu003Cpu003E下面来逐一介绍下这五个重要的特性。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRT4Gwk56bt5iOJ” img_width=”340″ img_height=”57″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h3″u003Eu003Cstrongu003EDynamic CDS Archivesu003Cu002Fstrongu003Eu003Cu002Fh1u003Eu003Cpu003E这一特性是在JEP310:Application Class-Data Sharing 基础上扩展而来的,Dynamic CDS Archives中的CDS指的就是Class-Data Sharing。u003Cu002Fpu003Eu003Cpu003E那么,这个JEP310是个啥东西呢?u003Cu002Fpu003Eu003Cpu003E我们知道在同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机都单独装载自己需要的所有类,启动成本和内存占用是比较高的。所以Java团队引入了CDS的概念,通过把一些核心类在每个JVM间共享,每个JVM只需要装载自己的应用类,启动时间减少了,另外核心类是共享的,所以JVM的内存占用也减少了。u003Cu002Fpu003Eu003Cpu003ECDS 只能作用于 Boot Class Loader 加载的类,不能作用于 App Class Loader 或者自定义的 Class Loader 加载的类。u003Cu002Fpu003Eu003Cpu003E在 Java 10 中,则将 CDS 扩展为 AppCDS,顾名思义,AppCDS 不止能够作用于 Boot Class Loader了,App Class Loader 和自定义的 Class Loader 也都能够起作用,u003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-6″u003E大大u003Cu002Fiu003E加大了 CDS 的适用范围。也就说开发自定义的类也可以装载给多个JVM共享了。u003Cu002Fpu003Eu003Cpu003EJava 10中包含的JEP310的通过跨不同Java进程共享公共类元数据来减少了内存占用和改进了启动时间。u003Cu002Fpu003Eu003Cpu003E但是,JEP310中,使用AppCDS的过程还是比较复杂的,需要有三个步骤:u003Cu002Fpu003Eu003Cpu003E1、决定要 Dump 哪些 Classu003Cu002Fpu003Eu003Cpu003E2、将类的内存 Dump 到归档文件中u003Cu002Fpu003Eu003Cpu003E3、使用 Dump 出来的归档文件加快应用启动速度u003Cu002Fpu003Eu003Cpu003E这一次的JDK 13中的JEP 350 ,在JEP310的基础上,又做了一些扩展。允许在Java应用程序执行结束时动态归档类,归档类将包括默认的基础层 CDS(class data-sharing)存档中不存在的所有已加载的应用程序类和库类。u003Cu002Fpu003Eu003Cpu003E也就是说,在Java 13中再使用AppCDS的时候,就不在需要这么复杂了。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRT7S2kzFTfre26″ img_width=”340″ img_height=”57″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h3″u003Eu003Cstrongu003EZGC: Uncommit Unused Memoryu003Cu002Fstrongu003Eu003Cu002Fh1u003Eu003Cpu003E在讨论这个问题之前,想先问一个问题,JVM的GC释放的内存会还给操作系统吗?u003Cu002Fpu003Eu003Cpu003EGC后的内存如何处置,其实是取决于不同的垃圾回收器的。因为把内存还给OS,意味着要调整JVM的堆大小,这个过程是比较耗费资源的。u003Cu002Fpu003Eu003Cpu003E在JDK 11中,Java引入了ZGC,这是一款可伸缩的低延迟垃圾收集器,但是当时只是实验性的。并且,ZGC释放的内存是不会还给操作系统的。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRch9qXQ7BMQAWT” img_width=”607″ img_height=”585″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003E而在Java 13中,JEP 351再次对ZGC做了增强,本次 ZGC 可以将未使用的堆内存返回给操作系统。之所以引入这个特性,是因为如今有很多场景中内存是比较昂贵的资源,在以下情况中,将内存还给操作系统还是很有必要的:u003Cu002Fpu003Eu003Culu003Eu003Cliu003Eu003Cpu003E1、那些需要根据使用量付费的容器u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E2、应用程序可能长时间处于空闲状态并与许多其他应用程序共享或竞争资源的环境。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E3、应用程序在执行期间可能有非常不同的堆空间需求。例如,启动期间所需的堆可能大于稍后在稳定状态执行期间所需的堆。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cu002Fulu003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002FRTJXJ1kBqzfCnu” img_width=”340″ img_height=”57″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h3″u003Eu003Cstrongu003EReimplement the Legacy Socket APIu003Cu002Fstrongu003Eu003Cu002Fh1u003Eu003Cpu003E使用易于维护和调试的更简单、更现代的实现替换 java.net.Socket 和 java.net.ServerSocket API。u003Cu002Fpu003Eu003Cpu003Ejava.net.Socket和java.net.ServerSocket的实现非常古老,这个JEP为它们引入了一个现代的实现。现代实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来使用它们。u003Cu002Fpu003Eu003Cpu003E运行一个实例化Socket和ServerSocket的类将显示这个调试输出。这是默认的(新的):u003Cu002Fpu003Eu003Cpreu003Ejava -XX:+TraceClassLoading JEP353 | grep Socketu003Cbru003E[0.033s][info ][class,load] java.net.Socket source: jrt:u002Fjava.baseu003Cbru003E[0.035s][info ][class,load] java.net.SocketOptions source: jrt:u002Fjava.baseu003Cbru003E[0.035s][info ][class,load] java.net.SocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.039s][info ][class,load] java.net.SocketImpl$$Lambda$1u002F0x0000000800b50840 source: java.net.SocketImplu003Cbru003E[0.042s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.042s][info ][class,load] sun.nio.ch.NioSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.043s][info ][class,load] sun.nio.ch.SocketDispatcher source: jrt:u002Fjava.baseu003Cbru003E[0.044s][info ][class,load] java.net.DelegatingSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.044s][info ][class,load] java.net.SocksSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.044s][info ][class,load] java.net.ServerSocket source: jrt:u002Fjava.baseu003Cbru003E[0.045s][info ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:u002Fjava.baseu003Cbru003E[0.045s][info ][class,load] java.net.ServerSocket$1 source: jrt:u002Fjava.baseu003Cu002Fpreu003Eu003Cpreu003Eu003Cpu003E上面输出的sun.nio.ch.NioSocketImpl就是新提供的实现。u003Cu002Fpu003Eu003Cu002Fpreu003Eu003Cpu003E如果使用旧的实现也是可以的(指定参数jdk.net.usePlainSocketImpl):u003Cu002Fpu003Eu003Cpreu003E$ java -Djdk.net.usePlainSocketImpl -XX:+TraceClassLoading JEP353 | grep Socketu003Cbru003E[0.037s][info ][class,load] java.net.Socket source: jrt:u002Fjava.baseu003Cbru003E[0.039s][info ][class,load] java.net.SocketOptions source: jrt:u002Fjava.baseu003Cbru003E[0.039s][info ][class,load] java.net.SocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.043s][info ][class,load] java.net.SocketImpl$$Lambda$1u002F0x0000000800b50840 source: java.net.SocketImplu003Cbru003E[0.046s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.047s][info ][class,load] java.net.AbstractPlainSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.047s][info ][class,load] java.net.PlainSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.047s][info ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:u002Fjava.baseu003Cbru003E[0.047s][info ][class,load] sun.net.ext.ExtendedSocketOptions source: jrt:u002Fjava.baseu003Cbru003E[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions source: jrt:u002Fjdk.netu003Cbru003E[0.047s][info ][class,load] java.net.SocketOption source: jrt:u002Fjava.baseu003Cbru003E[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:u002Fjdk.netu003Cbru003E[0.047s][info ][class,load] jdk.net.SocketFlow source: jrt:u002Fjdk.netu003Cbru003E[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions source: jrt:u002Fjdk.netu003Cbru003E[0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:u002Fjdk.netu003Cbru003E[0.048s][info ][class,load] jdk.net.LinuxSocketOptions source: jrt:u002Fjdk.netu003Cbru003E[0.048s][info ][class,load] jdk.net.LinuxSocketOptions$$Lambda$2u002F0x0000000800b51040 source: jdk.net.LinuxSocketOptionsu003Cbru003E[0.049s][info ][class,load] jdk.net.ExtendedSocketOptions$1 source: jrt:u002Fjdk.netu003Cbru003E[0.049s][info ][class,load] java.net.StandardSocketOptions source: jrt:u002Fjava.baseu003Cbru003E[0.049s][info ][class,load] java.net.StandardSocketOptions$StdSocketOption source: jrt:u002Fjava.baseu003Cbru003E[0.051s][info ][class,load] sun.net.ext.ExtendedSocketOptions$$Lambda$3u002F0x0000000800b5u003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-6″u003E144u003Cu002Fiu003E0 source: sun.net.ext.ExtendedSocketOptionsu003Cbru003E[0.057s][info ][class,load] java.net.DelegatingSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.057s][info ][class,load] java.net.SocksSocketImpl source: jrt:u002Fjava.baseu003Cbru003E[0.058s][info ][class,load] java.net.ServerSocket source: jrt:u002Fjava.baseu003Cbru003E[0.058s][info ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:u002Fjava.baseu003Cbru003E[0.058s][info ][class,load] java.net.ServerSocket$1 source: jrt:u002Fjava.baseu003Cu002Fpreu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h3″u003E上面的结果中,旧的实现java.net.PlainSocketImpl被用到了。u003Cu002Fh1u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRTJXJ7YR5xGDl” img_width=”340″ img_height=”57″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h3″u003Eu003Cstrongu003ESwitch Expressions (Preview)u003Cu002Fstrongu003Eu003Cu002Fh1u003Eu003Cpu003Eu003Cu002Fpu003Eu003Cpu003E在JDK 12中引入了Switch表达式作为预览特性。JEP 354修改了这个特性,它引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield, switch语句(不返回值)应该使用break。u003Cu002Fpu003Eu003Cpu003E在以前,我们想要在switch中返回内容,还是比较麻烦的,一般语法如下:u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003Eint i;u003Cbru003Eswitch (x) {u003Cbru003Ecase “1”:u003Cbru003Ei=1;u003Cbru003Ebreak;u003Cbru003Ecase “2”:u003Cbru003Ei=2;u003Cbru003Ebreak;u003Cbru003Edefault:u003Cbru003Ei = x.length;u003Cbru003Ebreak;u003Cbru003E}u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E在JDK13中使用以下语法:u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003Eint i = switch (x) {u003Cbru003Ecase “1” -> 1;u003Cbru003Ecase “2” -> 2;u003Cbru003Edefault -> {u003Cbru003Eint len = args[1].length;u003Cbru003Eyield len;u003Cbru003E}u003Cbru003E};u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E或者u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003Eint i = switch (x) {u003Cbru003Ecase “1”: yield 1;u003Cbru003Ecase “2”: yield 2;u003Cbru003Edefault: {u003Cbru003Eint len = args[1].length;u003Cbru003Eyield len;u003Cbru003E}u003Cbru003E};u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E在这之后,switch中就多了一个关键字用于跳出switch块了,那就是yield,他用于返回一个值。和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRTJXJ7uHXU5GZc” img_width=”340″ img_height=”57″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003Eu003Cstrongu003EText Blocks (Preview)u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003E在JDK 12中引入了Raw String Literals特性,但在发布之前就放弃了。这个JEP在引入多行字符串文字(text block)在意义上是类似的。u003Cu002Fpu003Eu003Cpu003Etext block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。u003Cu002Fpu003Eu003Cpu003E我们以前从外部copy一段文本串到Java中,会被自动转义,如有一段以下字符串:u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003E<html>u003Cbru003E<body>u003Cbru003E<p>Hello, Hollis<u002Fp>u003Cbru003E<u002Fbody>u003Cbru003E<u002Fhtml>u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E将其复制到Java的字符串中,会展示成以下内容:u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003E”<html>\n” +u003Cbru003E” <body>\n” +u003Cbru003E” <p>Hello, Hollis<u002Fp>\n” +u003Cbru003E” <u002Fbody>\n” +u003Cbru003E”<u002Fhtml>\n”;u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E即被自动进行了转义,这样的字符串看起来不是很直观,在JDK 13中,就可以使用以下语法了:u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003E”””u003Cbru003E<html>u003Cbru003E<body>u003Cbru003E<p>Hello, Hollis<u002Fp>u003Cbru003E<u002Fbody>u003Cbru003E<u002Fhtml>u003Cbru003E”””;u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E使用”””作为文本块的开始符合结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。u003Cu002Fpu003Eu003Cpu003E如常见的SQL语句:u003Cu002Fpu003Eu003Cpreu003Eu003Cpreu003EString query = “””u003Cbru003ESELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`u003Cbru003EWHERE `CITY` = ‘INDIANAPOLIS’u003Cbru003EORDER BY `EMP_ID`, `LAST_NAME`;u003Cbru003E”””;u003Cu002Fpreu003Eu003Cu002Fpreu003Eu003Cpu003E看起来就比较直观,清爽了。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRTLSNam5ZxLDlM” img_width=”340″ img_height=”57″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h3″u003Eu003Cstrongu003E总结u003Cu002Fstrongu003Eu003Cu002Fh1u003Eu003Cpu003Eu003Cu002Fpu003Eu003Cpu003E以上,就是JDK13中包含的5个特性,能够改变开发者的编码风格的主要有Text Blocks和Switch Expressions两个新特性,但是这两个特性还处于预览阶段。u003Cu002Fpu003Eu003Cpu003E而且,JDK13并不是LTS(长期支持)版本,如果你正在使用Java 8(LTS)或者Java 11(LTS),暂时可以不必升级到Java 13。u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRch9qvCBDMgaBS” img_width=”556″ img_height=”518″ alt=”Java 13 新特性全面解读” inline=”0″u003Eu003Cpu003E参考资料: u003Cu002Fpu003Eu003Cpu003Ehttps:u002Fu002Fopenjdk.java.netu002Fprojectsu002Fjdku002F13u002F u003Cu002Fpu003Eu003Cpu003Ehttps:u002Fu002Fmetebalciu003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-6″u003E.comu003Cu002Fiu003Eu002Fblogu002Fwhat-is-new-in-java-13u002Fu003Cu002Fpu003Eu003Cpu003Ehttps:u002Fu002Fu003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-4″u003Ewwwu003Cu002Fiu003E.jianshuu003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-6″u003E.comu003Cu002Fiu003Eu002Fpu002F890196bf529au003Cu002Fpu003Eu003Cpu003E作者简介:Hollis,知名技术博主,个人博客文章阅读量数百万,CSDN博客专家。工作地点杭州,主要从事金融,支付领域的Java开发,热衷于技术分享。u003Cu002Fpu003Eu003Cpu003E本文转载自Hollis公众号,专注原创技术文章,主要以Java相关技术为主,覆盖基础知识、底层原理、技术成长等话题。u003Cu002Fpu003Eu003Cpu003E【END】u003Cu002Fpu003E”

原文始发于:Java 13 新特性全面解读

主题测试文章,只做测试使用。发布者:熱鬧獨處,转转请注明出处:http://www.cxybcw.com/15065.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code