JDK13今日发布,带来5大新特性
JDK
JDK作为JAVA的核心,发展至今,已经更新到13版本了。
早在2017年8月,JCP执行委员会就已经提出将JAVA的发布频率修改调整为每六个月一次,新的发布周期将严格遵循这个时间点,每年的3月份和9月份将会发布新的JDK。
今日,JDK13正式发布,在官网上,我们可以看到JDK13的进展情况。
JDK13
可以看到,今日JDK13已经处于一般可用性阶段,即是JDK13从今日起可以正式使用了。
JDK13主要有5大特性:
JDK13新特性
下面我们具体来看看这5大新特性。
01.动态CDS档案
这一特性是在JEP310:AppCDS基础上扩展而来的,可以让Java应用程序在执行结束时动态归档类。归档类包括默认的基础层CDS存档中不存在的所有已加载的应用程序类和库类。
在JEP310上,使用AppCDS的过程还是比较复杂的,需要有三个步骤:
执行一次或多次试运行以创建班级列表
使用创建的类列表转储存档
运行存档
除此之外,JEP310仅适用于使用内置类加载器的应用程序。而对HotSpot中由用户定义的类加载器加载的归档类仅仅只有实验性支持,并且不容易使用。
而在JDK13中的JEP520中,可以在第一次运行应用程序期间执行自动存档生成。这将消除显式存档创建步骤(即上面的步骤2)。
也就是说,在Java 13中使用AppCDS的时候,就不在需要这么复杂的步骤了。
我们再来看看JDK13中动态档案中的共享空间
布局跟静态存档类似,动态存档元数据分为以下四个空格。不需要“md”空间。
rw:可读/可写数据
ro:只读数据
mc:蹦床
“ro”空间以只读方式映射,以启用跨进程共享。运行时在共享空间单独映射。
另外记忆储蓄功能:针对在同一主机上运行多个相关进程,我们可以使用两个级别的存档来提高内存共享。
比如,共享同一组库的程序时:
使用“-cp:lib.jar:foo.jar FooApp”运行的2个进程
使用“-cp:lib.jar:bar.jar BarApp”运行的4个进程
您可以仅为lib.jar中的类(以及这些应用程序使用的其他系统类)创建静态存档(使用类列表)。然后,创建两个不同的动态档案,一个用于“foo”应用程序,另一个用于“bar”应用程序。
这样,静态存档可以在所有6个进程中共享,动态存档可以在运行相同程序的进程之间共享。
02.ZGC:取消使用未使用的内存
我们知道在JDK 11中,Java引入了ZGC,这个可伸缩的低延迟垃圾收集器,但它只是实验性的,并没有得到正式的应用。并且,ZGC释放的内存是不会还给操作系统的,即使该内存长时间未使用,这样一来它就浪费了大量的资源。
在JDK13中,JEP351再次增强了ZGC,可以将未使用的堆内存返回给操作系统。
之所以新增这个特性,是为了不浪费某些场景中内存这个比较昂贵的资源。尤其是那些需要关注内存占用的应用程序和环境,例如:
通过使用支付资源的容器环境。
应用程序可能长时间处于空闲状态并与许多其他应用程序共享或竞争资源的环境。
应用程序在执行期间可能具有非常不同的堆空间要求。例如,启动期间所需的堆可能大于稳态执行期间稍后所需的堆。
JDK13提供这种功能,对于某些类别的用户来说它是非常有用的。将此功能添加到ZGC中将受到同一组用户的深度欢迎。
03.重新实现Legacy Socket API
JDK13中使用更简单、更现代的实现替换掉java.net.Socket和java.net.ServerSocketAPI,用最底层来实现,便于维护和调试。而且新的实现很容易适应用户模式线程,也就是光纤,目前正在Project Loom中进行探索。
JDK13中,用NioSocketImpl来替代旧的PlainSocketImpl。因为它的开发易于维护和调试。不需要自己的本机代码,它与New I / O(NIO)实现共享相同的JDK内部基础结构。它不需要使用线程堆栈进行I / O,因为它与现有的缓冲区缓存机制集成。
NioSocketImpl中使用java.util.concurrent锁而不是synchronized方法,以便将来可以很好地与光纤配合使用。
要注意的是:
在JDK13中,旧的实现不会删除,仍旧会保留在JDK中,这样做是为了降低二十多年后切换的风险。可以通过配置系统属性(jdk.net.usePlainSocketImpl)的方式来切换新旧实现。将来的某些版本将会删除PlainSocketImpl这个系统属性。
04.切换表达式(预览)
在JDK 12中引入了Switch表达式作为预览特性。JDK13中修改了这个特性,它引入了yield语句,用于switch返回值。这意味着,后续switch表达式(如果要返回值)应该使用yield。
switch
在以前,我们使用switch语句,用法是这样的:
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
break;
case TUESDAY:
System.out.println(7);
break;
case THURSDAY:
case SATURDAY:
System.out.println(8);
break;
case WEDNESDAY:
System.out.println(9);
break;
}
在这段代码中,有许多break语句,让程序不必要地冗长,并且这种视觉噪声经常掩盖难以调试的错误,其中缺少的break语句意味着意外掉落。
在JDK13中,引入了一种新形式的开关标签“ case L ->”,表示如果标签匹配,则只执行标签右侧的代码。并且还可以使用多个常量,用逗号分隔。
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
可以看到,新特性中的代码用法更加的简洁、明了。
另外,
新特性中用yield语句作为返回值用法:
int j = switch (day) {
case MONDAY -> 0;
case TUESDAY -> 1;
default -> {
int k = day.toString().length();
int result = f(k);
yield result;
}
};
或者
int j = switch (day) {
case MONDAY -> yield 0;
case TUESDAY -> yield 1;
default -> {
int k = day.toString().length();
int result = f(k);
yield result;
}
};
从JDK13开始,switch中就多了一个关键字yield用于跳出switch块,并且返回一个值。yield和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。
05.文字块(预览)
早在JDK 12中,就引入了Raw String Literals特性,但在发布之前就已经被撤回来。JDK13中的文字块与这个类似。
文本块是一个多行字符串文字,它避免了对大多数转义序列的需要,以可预测的方式自动格式化字符串,将文本块添加到Java语言,并在需要时让开发人员控制格式。
新特性主要有以下的几个目的:
通过简化表达跨越多行源代码的字符串,同时避免常见情况下的转义序列,简化编写Java程序的任务。
增强Java程序中字符串的可读性,表示用非Java语言编写的代码。
通过规定任何新构造可以表达与字符串文字相同的字符串集,并解释相同的转义序列,并像字符串文字一样进行操作,支持从字符串文字进行迁移。
我们以前从外部复制一段文本串到Java代码中,常常会被自动转义,例如以下字符串:
<html>
<body>
<p>Hello, world</p>
</body>
</html>
将其复制到java代码字符串中,将会是这样的:
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
可以看到,代码自主的进行了转义,而且看起来很不美观。
在JDK13中,使用"""作为开始符和结束符,直接放置多行的代码块,不需要任何的转义 ,看起来很干净。
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
还有,我们经常用到的SQL语句:
String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
"WHERE `CITY` = 'INDIANAPOLIS'\n" +
"ORDER BY `EMP_ID`, `LAST_NAME`;\n";
在JDK13中,可以这样用:
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
这样看起来就更加的直观了,让人一目了然。
总结
以上就是JDK13中5大新特性的相关信息了,就小编个人的看法,对我们编码工作有影响的就第4,5这两个新特性了,这两个特性将会大大缩减我们日后的编码工作,而且也会让我们的编码风格更加的直观,简洁。但是这两个新特性目前还只是预览阶段。
值得注意的是,JDK13并不是长期支持的版本,所以暂时可以不用升级到JDK13,保持现有的JDK版本就好了。