Java 13 新功能介绍

简介: Java 13 新功能介绍

微信图片_20220414172619.jpg

Java 13 by Alena Penkova

自从 Oracle 调整了 Java 的版本发布节奏之后,Java 版本发布越来越快,虽然都说 Java 版本任他发,我用 Java 8,不过新版本的 Java 功能还是要学习一下的。

Java 13 早在 2019 年 9 月就已经发布,虽然不是长久支持版本,但是也带来了不少新功能。

Java 13 官方下载:https://jdk.java.net/archive/

Java 13 官方文档:http://openjdk.java.net/projects/jdk/13/

Java 13 新功能

  1. JEP 350: 动态 CDS 存档
  2. JEP 351: ZGC,归还未使用的内存 (实验性)
  3. JEP 353: 重新实现 Socket API
  4. JEP 354: Switch 表达式 (二次预览)
  5. JEP 355: 文本块 (预览)

扩展:此文章属于 Java 新特性教程 系列,会介绍 Java 每个版本的新功能,可以点击浏览。

1. JEP 350 动态 CDS 存档

JVM 启动时有一步是需要在内存中加载类,而如果有多个 jar,加载第一个 jar 的速度是最慢的。这就延长了程序的启动时间,为了减少这个时间,Java 10 引入了应用程序类数据共享(CDS)机制,它可以把你想共享的类共享在程序之间,使不同的 Java 进程之间共享这个类来减少这个类占用的空间以及加载速度。不过 Java 10 中使用这个功能的步骤比较繁琐。

扩展阅读:Java 10 新功能介绍

而 Java 13 中的 AppCDS,允许 Java 应用在程序执行结束时(如果 JVM 没有崩溃)进行动态存档;存储的内容包括所有加载的应用类型类和使用的类库,这些存储的类库本来并不存在于默认的 CDS 存档中。

使用这个功能非常简单,只需要在程序启动时增加启动参数 。

# ArchiveClassesAtExit,程序结束时动态存档
bin/java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello
# SharedArchiveFile,使用指定存档启动
bin/java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello

2. JEP 351: ZGC,归还未使用的内存 (实验性)

在 Java 13 之前,ZGC 虽然在清理内存时导致的停顿时间非常少,但是即使内存已经长时间没有使用,ZGC 也不会将内存返还给操作系统,这对那些十分关注内存占用的应用程序非常不友好。

比如:

  • 资源按使用量付费的云上容器环境。
  • 应用虽然长时间闲置,但是占用了内存,导致运行的其他程序内存紧张。

而新增的这个功能,可以让 ZGC 归还长时间没有使用的内存给操作系统,这对某些用户来说十分友好。

3. JEP 353: 重新实现 Socket API

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

因此,在 Java 13 中引入了新的实现方式,使用了新的实现 NioSocketImpl 来代替老旧的 PlainSocketImpl 实现。虽然功能相同,但是老的方式在当前以及未来几个版本内不会删除,用户随时可以通过 -Djdk.net.usePlainSocketImpl 参数切换回老的实现方式,以兼容意外情况。

编写一个测试类可以发现这个变化。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Test {
    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

➜  develop ./jdk-13.0.2.jdk/Contents/Home/bin/java -XX:+TraceClassLoading Test.java | grep SocketImpl
[0.699s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.699s][info   ][class,load] java.net.SocketImpl$$Lambda$173/0x0000000800c37440 source: java.net.SocketImpl
[0.702s][info   ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
[0.702s][info   ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base
[0.713s][info   ][class,load] sun.nio.ch.NioSocketImpl$FileDescriptorCloser source: jrt:/java.base

但在 Java 12 并不是 NioSocketImpl

➜  develop ./jdk-12.0.2.jdk/Contents/Home/bin/java -XX:+TraceClassLoading Test.java | grep SocketImpl
[0.665s][info   ][class,load] java.net.SocketImpl source: jrt:/java.base
[0.665s][info   ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base
[0.665s][info   ][class,load] java.net.PlainSocketImpl source: jrt:/java.base
[0.665s][info   ][class,load] java.net.SocksSocketImpl source: jrt:/java.base
[0.666s][info   ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:/java.base

4. JEP 354: Switch 表达式 (二次预览)

你为什么不愿意使用使用 switch 表达式?我想其中一个原因应该是, switch 表达式的代码不够美观优雅,甚至有些啰嗦。比如像下面的例子。

package com.wdbyte;
public class Java13Switch {
    public static void main(String[] args) {
      //通过传入月份,输出月份所属的季节
      System.out.println(switchJava12Before("march"));
    }
    public static String switchJava12Before(String month) {
        String reuslt = null;
        switch (month) {
            case "march":
            case "april":
            case "may":
                reuslt = "春天";
                break;
            case "june":
            case "july":
            case "august":
                reuslt = "夏天";
                break;
            case "september":
            case "october":
            case "november":
                reuslt = "秋天";
                break;
            case "december":
            case "january":
            case "february":
                reuslt = "冬天";
                break;
        }
        return reuslt;
    }
}

而在 Java 12 中,已经对 switch 进行了改进,使之可以使用 cast L -> 表达式进行操作,且可以具有返回值,这样代码就更加美观使用了,不过这在 Java 12 中是一个预览功能。

// 通过传入月份,输出月份所属的季节
public static String switchJava12(String month) {
     return switch (month) {
        case "march", "april", "may"            -> "春天";
        case "june", "july", "august"           -> "夏天";
        case "september", "october", "november" -> "秋天";
        case "december", "january", "february"  -> "冬天";
        default -> "month erro";
    };
}

扩展阅读:Java 12 新特性介绍

而现在,在 Java 13 中,又对 switch 表达式进行了增强,增加了yield 关键词用于返回值,相比 break ,语义更加明确了。

public static String switchJava13(String month) {
    return switch (month) {
        case "march", "april", "may":
            yield "春天";
        case "june", "july", "august":
            yield "夏天";
        case "september", "october", "november":
            yield "秋天";
        case "december", "january", "february":
            yield "冬天";
        default:
            yield "month error";
    };
}

5. JEP 355: 文本块 (预览)

在这之前,如果我们把一个 JSON 赋值给字符串:

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"
    + "}";

终于不用写丑陋的长字符串了,从 Java 13 开始你可以使用文本块的方式定义字符串了。

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 13 中使用需要手动开启预览功能,这个功能在 Java 15 中正式发布。

如果你想尝试,可以去下载最新版了,玩的开心。

参考

  1. http://openjdk.java.net/projects/jdk/13/
  2. https://nipafx.dev/java-application-class-data-sharing/
  3. https://www.wdbyte.com/2020/02/jdk/jdk12-feature/
  4. https://mkyong.com/java/what-is-new-in-java-13/
相关文章
|
3月前
|
安全 Java API
Java中的Lambda表达式:简洁与功能的结合
Java中的Lambda表达式:简洁与功能的结合
412 211
|
3月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
460 64
|
2月前
|
存储 数据可视化 Java
Java Stream API 的强大功能
Java Stream API 是 Java 8 引入的重要特性,它改变了集合数据的处理方式。通过声明式语法,开发者可以更简洁地进行过滤、映射、聚合等操作。Stream API 支持惰性求值和并行处理,提升了代码效率和可读性,是现代 Java 开发不可或缺的工具。
Java Stream API 的强大功能
|
3月前
|
前端开发 JavaScript Java
Java 项目实战城市公园信息管理系统开发流程与实用功能实现指南
本系统基于Java开发,采用Spring Boot后端框架与Vue.js前端框架,结合MySQL数据库,构建了一个高效的城市公园信息管理系统。系统包含管理员、用户和保洁人员三大模块,涵盖用户管理、园区信息查询、订票预约、服务管理等功能,提升公园管理效率与服务质量。
139 6
|
3月前
|
安全 Java 数据库
Java 项目实战病人挂号系统网站设计开发步骤及核心功能实现指南
本文介绍了基于Java的病人挂号系统网站的技术方案与应用实例,涵盖SSM与Spring Boot框架选型、数据库设计、功能模块划分及安全机制实现。系统支持患者在线注册、登录、挂号与预约,管理员可进行医院信息与排班管理。通过实际案例展示系统开发流程与核心代码实现,为Java Web医疗项目开发提供参考。
189 2
|
3月前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用(223)
本文探讨了Java大数据与机器学习模型在生物信息学中基因功能预测的优化与应用。通过高效的数据处理能力和智能算法,提升基因功能预测的准确性与效率,助力医学与农业发展。
|
4月前
|
Java API
Java API中Math类功能全景扫描
在实际使用时,这些方法的精确度和性能得到了良好的优化。当处理复杂数学运算或高精度计算时,`Math`类通常是足够的。然而,对于非常精细或特殊的数学运算,可能需要考虑使用 `java.math`包中的 `BigDecimal`类或其他专业的数学库。
127 11
|
4月前
|
Java API
深入解析Java API中Object类的功能
了解和合理运用 Object类的这些方法,对于编写可靠和高效的Java应用程序至关重要。它们构成了Java对象行为的基础,影响着对象的创建、识别、表达和并发控制。
88 0
|
4月前
|
消息中间件 监控 Java
借助最新技术构建 Java 邮件发送功能的详细流程与核心要点分享 Java 邮件发送功能
本文介绍了如何使用Spring Boot 3、Jakarta Mail、MailHog及响应式编程技术构建高效的Java邮件发送系统,涵盖环境搭建、异步发送、模板渲染、测试与生产配置,以及性能优化方案,助你实现现代化邮件功能。
198 0