Java SE 13 新增特性

Java SE 13 新增特性

作者:Grey

原文地址:Java SE 13 新增特性

源码

源仓库: Github:java_new_features

镜像仓库: GitCode:java_new_features

新版 Switch 使用方式

switch语句增加了 yield 关键字表示返回值,这个特性在Java SE 13中是预览特性,在Java SE 14正式引入。代码如下:

注:如果你用Java SE 12运行上述代码,需要指定--enable-preview参数,如果使用 Intellij IDEA ,参考How to Enable Java Preview Features and Run Code from IntelliJ IDEA

package git.snippets.jdk13;  /**  * switch yield功能  * jdk13 实验性功能  * 到jdk14 正式使用  * @author <a href="mailto:410486047@qq.com">Grey</a>  * @date 2021/11/29  * @since 13  */ public class SwitchYield {     public static void main(String[] args) {         String t = test("apple");         System.out.println(t);         String m = test("abc");         System.out.println(m);     }      private static String test(String c) {         return switch (c) {             case "apple", "Apple":                 yield "苹果";             case "banana":                 yield "香蕉";             default:                 yield "无法识别";         };     } } 

输出结果

苹果 无法识别 

文本块(预览功能)

为了定义一个多行字符串,我们习惯于使用转义序列来处理字符串中包含的换行和双引号。例如,一个SQL语句看起来像这样

String sql =     "SELECT id, firstName, lastName FROM Employee/n"         + "WHERE departmentId = /"IT/"/n"         + "ORDER BY lastName, firstName"; String content = "{/n"                 + "    /"upperSummary/": null,/n"                 + "    /"sensitiveTypeList/": null,/n"                 + "    /"gmtModified/": /"2011-08-05 10:50:09/",/n"                 + "    /"lowerGraph/": null,/n"                 + "    /"signature/": /"/",/n"                 + "    /"appName/": /"xxx/",/n"                 + "    /"lowerSummary/": null,/n"                 + "    /"gmtCreate/": /"2011-08-05 10:50:09/",/n"                 + "    /"type/": /"CALL/",/n"                 + "    /"name/": /"xxxx/",/n"                 + "    /"subType/": /"yyy/",/n"                 + "    /"id/": 1,/n"                 + "    /"projectId/": 1,/n"                 + "    /"status/": 1/n"                 + "}"; 

JDK Enhancement Proposal 355允许我们以更可读的方式编写这样的字符串。

String sql = """     SELECT id, firstName, lastName FROM Employee     WHERE departmentId = "IT"     ORDER BY lastName, firstName"""; String content2 = """         {         "upperSummary": null,         "sensitiveTypeList": null,         "gmtModified": "2011-08-05 10:50:09",         "lowerGraph": null,         "signature": "",         "appName": "xxx",         "lowerSummary": null,         "gmtCreate": "2011-08-05 10:50:09",         "type": "CALL",         "name": "xxxx",         "subType": "yyy",         "id": 1,         "projectId": 1,         "status": 1     }                  """; 

文本块在Java SE 13属于预览功能,在Java SE 15中正式启用

Socket API 新实现方式

java.net.Socket 和 java.net.ServerSocket 类早在 Java 1.0 时就已经引入了,它们的实现的 Java 代码和 C 语言代码的混合,维护和调试都十分不易;而且这个实现还存在并发问题,有时候排查起来也很困难。

因此,在 Java 13 中引入了新的实现方式,使用了新的实现 NioSocketImpl 来代替老旧的 PlainSocketImpl 实现。用户随时可以通过 -Djdk.net.usePlainSocketImpl 参数切换回老的实现方式,以兼容意外情况。代码如下

package git.snippets.jdk13;  import java.io.IOException; import java.net.ServerSocket; import java.net.Socket;  /**  * 新版Socket API 使用了新的实现 NioSocketImpl 来代替老旧的 PlainSocketImpl 实现。  * 需要增加-XX:+TraceClassLoading参数  *  * @author <a href="mailto:410486047@qq.com">Grey</a>  * @date 2022/8/20  * @since 13  */ public class NewSocketAPI {     public static void main(String[] args) {         try (ServerSocket serverSocket = new ServerSocket(8000)) {             boolean running = true;             while (running) {                 Socket clientSocket = serverSocket.accept();                 //do something with clientSocket             }         } catch (IOException e) {             e.printStackTrace();         }     } } 

使用 Java 13 运行,通过参数 -XX:+TraceClassLoading 追踪加载的类,日志中可以看到 NioSocketImpl。

[0.099s][info   ][class,load] java.util.Properties$LineReader source: shared objects file [0.099s][info   ][class,load] java.io.FileInputStream$1 source: shared objects file [0.100s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base [0.100s][info   ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base [0.100s][info   ][class,load] sun.nio.ch.NativeDispatcher source: jrt:/java.base [0.100s][info   ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base 

但在 Java 12 并不是 NioSocketImpl。

[0.120s][info   ][class,load] java.util.concurrent.ConcurrentSkipListMap$Node source: shared objects file [0.120s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base [0.120s][info   ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base [0.120s][info   ][class,load] java.net.PlainSocketImpl source: jrt:/java.base [0.120s][info   ][class,load] java.net.SocksSocketImpl source: jrt:/java.base 

ZGC: 取消提交未使用的内存

ZGC 是 Java SE 11 中引入的一个实验性垃圾收集器,它承诺在10毫秒或更短的时间内实现 stop-the-world 。

JDK Enhancement Proposal 351扩展了 ZGC 的功能,以便在特定时间后将未使用的堆内存返回给操作系统。

使用-XX:ZUncommitDelay,你可以指定ZGC返回未使用内存的时间,单位是秒。默认情况下,这个值是300秒。

该功能默认是启用的,可以用-XX:-ZUncommit来禁用。

ZGC 将在 Java SE 15 中达到生产状态。

动态 CDS 档案

Java SE 10 中引入了应用类数据共享–一个允许创建所谓共享存档文件的功能。这个文件包含了所使用平台的 JVM 所要求的二进制形式的应用类。该文件通过内存映射的 I/O 映射到 JVM 的内存中。

直到现在,创建这个文件还相对复杂。首先,我们必须在应用程序的测试运行期间转储一个类列表。只有在第二步,我们才能从这个列表中生成共享档案。

java -Xshare:off -XX:+UseAppCDS     -XX:DumpLoadedClassList=helloworld.lst     -cp target/helloworld.jar eu.happycoders.appcds.Main  java -Xshare:dump -XX:+UseAppCDS     -XX:SharedClassListFile=helloworld.lst     -XX:SharedArchiveFile=helloworld.jsa     -cp target/helloworld.jar 

JDK Enhancement Proposal 350简化了这个过程。从 Java SE 13 开始,你可以指定-XX:ArchiveClassesAtExit参数,在应用程序执行结束时生成共享存档。不再需要额外的参数-Xshare:on-XX:+UseAppCDS了。

java -XX:ArchiveClassesAtExit=helloworld.jsa     -cp target/helloworld.jar eu.happycoders.appcds.Main 

创建的共享存档也比以前小得多。因为它现在只包含应用程序的类。

从 Java SE 13 开始,共享存档的使用方法如下。

java -XX:SharedArchiveFile=helloworld.jsa     -cp target/helloworld.jar eu.happycoders.appcds.Main 

更多

Java SE 7及以后各版本新增特性

参考资料

official Java 13 Release Notes

Java 13 Features (with Examples)

Java ByteBuffer Example: How to Use flip() and compact()

Application Class-Data Sharing

Java 13 新功能介绍

商匡云商
Logo
注册新帐户
对比商品
  • 合计 (0)
对比
0
购物车