新版 Switch 应用形式

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

注: 如果你用 Java SE 12 运行上述代码,须要指定 --enable-preview 参数,如果应用 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.Mainjava -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面试》材料,阿里,腾讯,字节,美团,饿了么等大厂