本文主要介绍明天Java13的发布,以及最新最新特性的解读。通过示例代码非常详细的介绍,对大家的学习或者工作都有一定的参考价值。有需要的朋友下面跟边肖学习。
2017年8月,JCP执行委员会提议将Java的发布频率改为每半年一次。新的发布周期严格遵循时间点,将在每年的3月和9月发布。
目前在JDK官网可以看到JDK 13的进度,JDK 13的最新版本将于2019年9月17日发布。
目前JDK13处于发布候选阶段,将于9月17日正式发布。目前,该版本包含的所有功能都已修复,主要包括以下五项:
JEP 350,动态光盘档案
JEP 351,ZGC:取消提交未使用的内存
JEP 353,重新实现传统套接字API
JEP 354:切换表达式(预览)
JEP 355,文本块(预览)
下面我们就来逐一介绍这五个重要特性。
Dynamic CDS Archives
这个特性是从JEP310:应用类-数据共享扩展而来,动态CDS档案中的CDS指的是类-数据共享。
那么,这个JEP310是什么?
我们知道,在同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机分别加载自己需要的所有类,那么启动成本和内存占用都会比较高。因此,Java团队引入了CDS的概念。通过在每个JVM之间共享一些核心类,每个JVM只需要加载自己的应用程序类,这减少了启动时间。另外,核心类是共享的,所以JVM的内存占用也减少了。
CDS只能应用于Boot类加载器加载的类,不能应用于App类加载器或自定义类加载器加载的类。
在Java 10中,CDS被扩展为AppCDS。顾名思义,AppCDS不仅可以作用于引导类加载器,还可以作用于App类加载器和自定义类加载器,大大扩展了CDS的应用范围。也就是说,开发自定义类也可以被多个JVM加载和共享。
Java 10中包含的JEP310通过在不同的Java进程之间共享公共的类元数据,减少了内存占用并缩短了启动时间。
但是,在JEP310中,使用AppCDS的过程相当复杂,有三个步骤:
1.决定转储哪个类。
2.将类的内存转储到归档文件中。
3.使用转储中的归档文件来加速应用程序的启动。
这次JDK 13的JEP 350在JEP310的基础上做了一些扩展。允许在Java应用程序执行结束时动态归档类,归档类将包括所有加载的应用程序类和默认CDS(类数据共享)归档中不存在的库类。
也就是说,在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。网。计算机网络服务器套接字的实现非常古老,这个JEP为它们引入了一个现代的实现。现代实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来使用它们。
运行一个实例化(电源)插座和服务器套接字的类将显示这个调试输出。这是默认的(新的):
Java-XX:跟踪类加载jep 353 | grep套接字
[0.033s][info ][class,load]Java。网。socket源码:jrt:/Java。基础
[0.035s][info ][class,load] java.net.SocketOptions来源:jrt:/java.base
[0.035s][信息][类,加载]Java。网。socketimpl来源:jrt:/Java。基础
[0.039s][info ][class,load]Java . net . socketimpl $ $ Lambda $ 1/0x 000000800 b 50840来源:Java。网。socketimpl
[0.042s][info ][class,load]孙。网。平台socketimpl来源:jrt:/java.base
[0.042s][info ][class,load] sun.nio.ch.NioSocketImpl来源:jrt:/java.base
[0.043s][info ][class,load]孙。nio。栗色套接字调度程序来源:jrt:/java.base
[0.044s][info ][class,load]Java。网。delegatingsocketimpl来源:jrt:/java.base
[0.044s][info ][class,load] java.net.SocksSocketImpl来源:jrt:/java.base
[0.044s][info ][class,load]Java。网。服务器套接字源码:jrt:/Java。基础
[0.045s][信息][类,负载]JDK。内部。访问。javanetsocketaccess来源:jrt:/java.base
[0.045s][信息][类,加载]Java。网。服务器套接字$ 1来源:jrt:/Java。基础
上面输出的孙就是新提供的实现。
如果使用旧的实现也是可以的(指定参数jdk.net.usePlainSocketImpl):
$ Java-djdk。网。useplainsocketimpl-XX:TraceClassLoading jep 353 | grep套接字
[0.037s][信息][类,加载]Java。网。socket源码:jrt:/Java。基础
[0.039s][信息][类,加载]Java。网。套接字选项来源:jrt:/Java。基础
[0.039s][信息][类,加载]Java。网。socketimpl来源:jrt:/Java。基础
[0.043s][info ][class,load]Java . net . socketimpl $ $ Lambda $ 1/0x 0000000800 b 50840来源:Java。网。socketimpl
[0.046s][info ][class,load]孙。网。平台socketimpl来源:jrt:/java.base
[0.047s][信息][类,加载]Java。网。abstractplainsocketimpl来源:jrt:/java.base
[0.047s][info ][class,load] java.net.PlainSocketImpl来源:jrt:/java.base
[0.047s][信息][类,加载]Java。网。abstractplainsocketimpl $ 1 source:jrt:/Java。基础
[0.047s][info ][class,load]孙。网。延伸文件系统extendedsocketoptions来源:jrt:/java.base
[0.047s][信息][类,负载]JDK。网。extendedsocketoptions来源:jrt:/jdk.net
[0.047s][信息][类,加载]Java。网。套接字选项来源:jrt:/Java。基础
[0.047s][信息][类,负载]JDK。网。extendedsocketoptions $ ExtSocketOption来源:jrt:/jdk.net
[0.047s][info ][class,load] jdk.net.SocketFlow来源:jrt:/jdk.net
[0.047s][信息][类,负载]JDK。网。extendedsocketoptionsPlatformSocketOptions来源:jrt:/jdk.net
[0.047s][信息][类,负载]JDK。网。extendedsocketoptions $ PlatformSocketOptions $ 1来源:jrt:/jdk.net
[0.048s][信息][类,负载]JDK。网。linuxsocketoptions来源:jrt:/jdk.net
[0.048s][信息][类,负载]JDK。网。Linux socket options $ $ Lambda $ 2/0x 0000000800 b 51040来源:JDK。网。linuxssocketoptions
[0.049s][信息][类,负载]JDK。网。来源:jrt:/JDK。网
[0.049s][信息][类,加载]Java。网。标准插座选项源代码:jrt:/java.base
[0.049s][信息][类,加载]Java。网。标准套接字选项$ StdSocketOption源代码:jrt:/java.base
[0.051s][info ][class,load]孙。网。延伸文件系统extendedsocketoptions $ $ Lambda $ 3/0x 0000000800 b 51440来源:孙。网。extendedsocketoptions
[0.057s][信息][类,加载]Java。网。delegatingsocketimpl来源:jrt:/java.base
[0.057s][信息][类,加载]Java。网。sockssocketimpl来源:jrt:/Java。基础
[0.058s][信息][类,加载]Java。网。服务器套接字源码:jrt:/Java。基础
[0.058s][信息][类,负载]JDK。内部。访问。javanetsocketaccess来源:jrt:/java.base
[0.058s][信息][类,加载]Java。网。服务器套接字$ 1来源:jrt:/Java。基础
上面的结果中,旧的实现java.net.PlainSocketImpl被用到了。
Switch Expressions (Preview)
JDK 12中引入了开关表达式作为预览功能。JEP 354通过引入用于返回值的yield语句修改了这个特性。这意味着switch表达式(返回值)应该使用yield,switch语句(无返回值)应该使用break。
以前我们想在switch中返回内容是比较麻烦的。一般语法如下:
int I;
开关(x) {
案例“1”:
I=1;
打破;
案例“2”:
I=2;
打破;
默认值:
I=x . length();
打破;
}
在JDK13中使用以下语法:
int i=switch (x) {
案例“1”-1;
案例' 2 '-2;
默认- {
int len=args[1]。长度();
屈服透镜;
}
};
或者
int i=switch (x) {
案例“1”:产量1;
案例“2”:产量2;
默认值:{
int len=args[1]。长度();
屈服透镜;
}
};
之后,switch中还有一个关键字要跳出switch块,就是yield,用来返回值。return和return的区别在于return会直接跳出当前的循环或方法,而yield只会跳出当前的switch块。
Text Blocks (Preview)
原始字符串文字特性是在JDK 12中引入的,但是在发布之前就被放弃了。这个JEP在引入多行文本块的意义上是类似的。
文本块,文本块,是多行字符串文字。它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,并让开发人员在需要时控制格式化。
我们曾经将一个文本字符串从外部复制到Java中,它会被自动转义,比如下面的字符串:
超文本标记语言
身体
pHello,世界/p
/body
/html
将其复制到Java的字符串中,它将显示以下内容:
html\n '
正文\n '
' pHello,世界/p\n '
/body\n '
/html \ n ';
也就是自动转义。这样的字符串看起来不是很直观。在JDK版本13中,您可以使用以下语法:
'''
超文本标记语言
身体
pHello,世界/p
/body
/html
''';
使用“”作为文本块的开始和结束字符,可以在其中放置多行字符串,而不需要任何转义。看起来很清爽。
比如常见的SQL语句:
字符串查询=' ' '
从“EMPLOYEE_TB”中选择“EMP_ID”、“LAST_NAME”
“城市”=“印第安纳波利斯”
ORDER BY `EMP_ID ',` last _ name ';
''';
看起来更直观,更清爽。
总结
这是JDK13中包含的五个功能。有两个新功能可以改变开发者的编码风格:文本块和开关表达式,但这两个功能仍处于预览阶段。
此外,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
这就是本文的全部内容。希望对大家的学习有帮助,支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。