• Java SE 13 新增特性


    Java SE 13 新增特性

    作者:Grey

    原文地址:

    博客园:Java SE 13 新增特性

    CSDN:Java SE 13 新增特性

    源码

    源仓库: Github: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 Grey
     * @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 "无法识别";
            };
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    输出结果

    苹果
    无法识别
    
    • 1
    • 2

    文本块(预览功能)

    为了定义一个多行字符串,我们习惯于使用转义序列来处理字符串中包含的换行和双引号。例如,一个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"
                    + "}";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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
        }
                     """;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    文本块在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 Grey
     * @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();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    使用 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    但在 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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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
    
    • 1
    • 2

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

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

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

    更多

    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 新功能介绍

  • 相关阅读:
    ElastaticSearch -- es客户端RestHighLevelClient
    #ifndef 与 #program once
    用CSS+SVG做一个优雅的环形进度条
    序列合并--优先队列的应用
    android 消除字体上下间距
    内存屏障 && volatile
    半导体分立器件动态测试参数有哪些?纳米软件半导体测试厂商如何助力测试?
    【汇编语言03】第2章 寄存器——实验1:查看CPU和内存,用机器指令和汇编指令编程
    视频编解码 — 卡顿与花屏
    scrm系统源码该如何选择?快鲸scrm系统源码优势明显
  • 原文地址:https://blog.csdn.net/hotonyhui/article/details/126436275