Java 13 - 快速指南


Java 13 - 概述

Java 13 是一个主要功能版本,它为 JAVA 带来了许多 JVM 特定的更改,但很少有语言特定的更改。它遵循 Java 发布节奏,从 Java 10 开始引入,并于 2019 年 9 月发布,即 Java 12 发布仅六个月后。

Java 13 是非 LTS 版本。

新功能

以下是 Java 13 中引入的主要新功能。

  • JEP 354 - Switch 表达式- 预览功能允许 switch 通过产量使用返回值。

  • JEP 355 - 文本块- 预览功能,可轻松处理 JSON、XML 等多行字符串。

  • 字符串新方法- 添加到字符串以处理文本块的新方法。

  • JEP 353 - 套接字 API 重新实现- 重写底层 API。

  • FileSystems.newFileSystem() - 添加了三个新方法以使其易于使用。

  • DOM/SAX 工厂- 添加了新方法以添加命名空间支持。

  • 动态 CDS 存档- 可以轻松创建 CDS 存档。

  • JEP 351 - ZGC 增强- ZGC 增强以将未使用的堆内存返回给操作系统。

Java 13 通过新方法和选项增强了众多 API。我们将在接下来的章节中看到这些变化。

Java 13 - 环境设置

本地环境设置

如果您想设置自己的 Java 编程语言环境,那么本节将指导您完成整个过程。请按照以下步骤设置您的 Java 环境。

Java SE 可供免费下载。要下载 ,请单击此处,请下载与您的操作系统兼容的版本。

按照说明下载 Java,然后运行​​.exe以在您的计算机上安装 Java。在计算机上安装 Java 后,您需要设置环境变量以指向正确的安装目录。

设置 Windows 2000/XP 的路径

假设您已将 Java 安装在 c:\Program Files\java\jdk 目录中 -

  • 右键单击“我的电脑”并选择“属性”。

  • 单击“高级”选项卡下的“环境变量”按钮。

  • 现在,编辑“Path”变量并在其末尾添加 Java 可执行文件目录的路径。例如,如果路径当前设置为C:\Windows\System32,则按以下方式编辑它

    C:\Windows\System32;c:\Program Files\java\jdk\bin

设置Windows 95/98/ME的路径

假设您已将 Java 安装在 c:\Program Files\java\jdk 目录中 -

  • 编辑“C:\autoexec.bat”文件并在末尾添加以下行 -

    SET PATH=%PATH%;C:\Program Files\java\jdk\bin

设置 Linux、UNIX、Solaris、FreeBSD 的路径

应将环境变量 PATH 设置为指向 Java 二进制文件的安装位置。如果您在执行此操作时遇到问题,请参阅您的 shell 文档。

例如,如果您使用 bash 作为 shell,那么您可以在.bashrc末尾添加以下行-

    export PATH=/path/to/java:$PATH'

流行的 Java 编辑器

要编写 Java 程序,您需要一个文本编辑器。市场上还有更复杂的 IDE。最流行的简要描述如下 -

  • 记事本- 在 Windows 计算机上,您可以使用任何简单的文本编辑器,例如记事本(本教程推荐)或写字板。Notepad++ 也是一个免费的文本编辑器,增强了功能。

  • Netbeans - 它是一个开源且免费的 Java IDE,可以从https://www.netbeans.org/index.html下载。

  • Eclipse - 它也是由 Eclipse 开源社区开发的 Java IDE,可以从https://www.eclipse.org/下载。

IDE或集成开发环境,提供所有常见的工具和设施来帮助编程,例如源代码编辑器、构建工具和调试器等。

Java 13 - 开关表达式

Java 12 向 Switch 语句引入了表达式,并将其作为预览功能发布。Java 13 添加了一个新的yield 构造来从 switch 语句返回值。它仍然是预览功能。

考虑以下示例:

ApiTester.java

例子

public class APITester {

   public static void main(String[] args) {
      System.out.println("Old Switch");
      System.out.println(getDayTypeOldStyle("Monday"));
      System.out.println(getDayTypeOldStyle("Saturday"));
      System.out.println(getDayTypeOldStyle(""));

      System.out.println("New Switch");
      System.out.println(getDayType("Monday"));
      System.out.println(getDayType("Saturday"));
      System.out.println(getDayType(""));
   }

   public static String getDayType(String day) {

      var result = switch (day) {
         case "Monday", "Tuesday", "Wednesday","Thursday", "Friday" -> yield "Weekday";
         case "Saturday", "Sunday" -> yield "Weekend";
         default -> "Invalid day.";
      };
      return result;
   }

   public static String getDayTypeOldStyle(String day) {
      String result = null;

      switch (day) {
         case "Monday":
         case "Tuesday":
         case "Wednesday":
         case "Thursday":
         case "Friday":
            result = "Weekday";
            break;
         case "Saturday": 
         case "Sunday":
            result = "Weekend";
            break;
         default:
            result =  "Invalid day.";            
      }

      return result;
   }
}

编译并运行程序

$javac -Xlint:preview --enable-preview -source 13 APITester.java

$java --enable-preview APITester

输出

Old Switch
Weekday
Weekend
Invalid day.
New Switch
Weekday
Weekend
Invalid day.

Java 13 - 文本块

Java 13 引入了文本块来处理多行字符串,如 JSON/XML/HTML 等。这是一个预览功能。

  • 文本块允许轻松编写多行字符串,而无需使用 \r\n。

  • 文本块字符串具有与字符串相同的方法,如 contains()、indexOf() 和 length() 函数。

例子

考虑以下示例:

ApiTester.java

public class APITester {

   public static void main(String[] args) {
      String stringJSON = "{\r\n" 
         + "\"Name\" : \"Mahesh\",\r\n" 
         + "\"RollNO\" : \"32\"\r\n" 
         + "}";  
   
      System.out.println(stringJSON);
	  
	  String textBlockJSON = """
         {
            "name" : "Mahesh",
            "RollNO" : "32"
         }
         """;
      System.out.println(textBlockJSON);
	  
	  System.out.println("Contains: " + textBlockJSON.contains("Mahesh"));
	  System.out.println("indexOf: " + textBlockJSON.indexOf("Mahesh"));
	  System.out.println("Length: " + textBlockJSON.length());
   }   
}

编译并运行程序

$javac -Xlint:preview --enable-preview -source 13 APITester.java

$java --enable-preview APITester

输出

{
"Name" : "Mahesh",
"RollNO" : "32"
}
{
   "name" : "Mahesh",
   "RollNO" : "32"
}

Contains: true
indexOf: 15
Length: 45

Java 13 - 文本块方法

Java 12 引入了文本块来处理多行字符串(如 JSON/XML/HTML 等),并向 String 类添加了新方法来处理文本块。这是一个预览功能。

  • stripIndent() - 删除字符串开头和结尾的偶然空格。

  • translateEscapes() - 根据字符串语法翻译转义序列。

  • formatted() - 类似于 String format() 方法,支持文本块字符串的格式化。

例子

考虑以下示例:

ApiTester.java

public class APITester {

   public static void main(String[] args) {
	  String textBlockJSON = """
         {
            "name" : "%s",
            "RollNO" : "%s"
         }
         """.formatted("Mahesh", "32");
      System.out.println(textBlockJSON);
   }   
}

编译并运行程序

$javac -Xlint:preview --enable-preview -source 13 APITester.java

$java --enable-preview APITester

输出

{
"Name" : "Mahesh",
"RollNO" : "32"
}
{
   "name" : "Mahesh",
   "RollNO" : "32"
}

Contains: true
indexOf: 15
Length: 45

Java 13 - 套接字 API 重新实现

Java 13 重新实现了 Java Socket API。旧的 Socket API(如java.net.Socketjava.net.ServerSocket)已被替换。

  • PlainSocketImpl 不再使用,现在 Socket API 提供者指向 NioSocketImpl。

  • 新的实现利用 java.nio 基础设施来实现更好的并发性和 I/O 控制。

  • 新的实现与使用旧实现的代码向后兼容。

  • 新的实现现在是 Java 12 的默认实现。

  • 可以通过多种方式选择旧的实现:

    • 将系统属性 jdk.net.usePlainSockteImpl 设置为 true。

    • 使用 -Djdk.net.usePlainSocketImpl 选项运行 java。

    • 更新 ${java.home}/conf/net.properties 中提供的 JDK 网络配置文件。

  • 旧的实现和选择旧实现的系统属性将从未来版本中删除。

Java 13 - 其他更改

Java 13 向 java.nio.file.FileSystems 引入了三种新方法,可以轻松地将文件内容视为文件系统。

  • 新文件系统(路径)

  • newFileSystem(路径, Map<字符串, ?>)

  • newFileSystem(路径, Map<String, ?>, ClassLoader)

以下是语言中添加的其他主要更改。

  • java.time – 添加了日本纪元名称

  • javax.crypto – MS 下一代密码学 (CNG) 支持

  • javax.security – 添加了 jdk.sasl.disabledMechanisms 属性来禁用 SASL 机制

  • javax.xml.crypto – 引入字符串常量来表示 Canonical XML 1.1 URI

  • javax.xml.parsers – 添加用于实例化 DOM 和 SAX 工厂以支持命名空间的方法

  • Unicode 支持升级至版本 12.1

  • 添加了 Kerberos 主体名称规范化支持,支持跨领域引用。

API 标记为删除

  • JDK 1.4 之前的 SocketImpl 实现

  • javax.security.cert API

  • 雷米克

  • javadoc 工具旧功能

其他详细信息可在以下链接中找到。建议删除的 API。

Java 13 - 动态 CDS 存档

CDS(类数据共享)是 JVM 的一项重要功能,可缩短应用程序加载的启动时间。由于它允许在不同的 JVM 之间共享类元数据,因此减少了启动时间和内存占用。Java 10 通过提供 AppCDS、应用程序 CDS 增强了 CDS,使开发人员能够将应用程序类包含在共享存档中。Java 12 将 CDS 存档设置为默认值。

但创建 CDS 的过程非常繁琐,因为开发人员必须对其应用程序进行多次试验,以创建类列表作为第一步,然后将该类列表转储到存档中。然后,该存档可用于在 JVM 之间共享元数据。

从Java 13开始,现在java有了动态归档。现在,开发人员可以在应用程序退出时生成共享存档。所以不再需要试运行。

以下步骤展示了如何使用选项 -XX:ArchiveClassesAtExit 并传递存档名称在默认系统存档之上创建动态共享存档。

$java -XX:ArchiveClassesAtExit=sharedApp.jar -cp APITester.jar APITester

生成共享存档后,可以使用 -XX:SharedArchiveFile 选项来运行应用程序。

$java -XX:SharedArchiveFile=sharedApp.jar -cp APITester.jar APITester

例子

考虑以下示例:

API测试器.java

public class APITester {
   public static void main(String[] args) {
      System.out.println("Welcome to TutorialsPoint.");
   }   
}

编译并运行程序

$javac APITester.java

$jar cf APITester.jar APITester.class

$java -XX:ArchiveClassesAtExit=sharedApp.jsa -cp APITester.jar APITester

$java -XX:SharedArchiveFile=sharedApp.jsa -cp APITester.jar APITester

输出

Welcome to TutorialsPoint.

Java 13 - ZGC 增强

ZGC 或 Z 垃圾收集器是随 Java 11 引入的,作为一种低延迟垃圾收集机制。ZGC 确保垃圾收集暂停时间不依赖于堆大小。无论堆大小是 2MB 还是 2GB,它都不会超过 10 毫秒。

但 ZGC 在将未使用的堆内存返回给操作系统方面存在限制,就像其他 HotSpot VM GC(例如 G1 和 Shenandoah)一样。以下是 Java 13 所做的增强:

  • 默认情况下,ZGC 将未提交的内存返回给操作系统,直到达到最大堆大小。

  • ZGC 通过减少内存占用来提高性能。

  • ZGC 现在支持 16 TB 的堆大小,而之前的大小限制为 4 TB。

为了回到 Java 11 的垃圾收集方式,我们可以使用以下选项:

  • 使用 -XX:-ZUncommit 选项

  • 将 -Xms 和 -Xmx 堆大小设置为相同。