Java 14 - 快速指南


Java 14 - 概述

Java 14 是一个主要功能版本,它为 JAVA 带来了许多 JVM 特定的更改和语言特定的更改。它遵循 Java 发布节奏,从 Java 10 开始引入,并于 2020 年 3 月 17 日发布,距 Java 13 发布仅六个月。

Java 14 是非 LTS 版本。

新功能

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

  • JEP 361 - Switch 表达式- 现在是一个标准功能,允许 switch 通过产量使用返回值。

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

  • JEP 305 - instanceOf 的模式匹配- 增强了 instanceOf 运算符以携带谓词。

  • JEP 358 - NullPointerException 消息- NullPointerException 现在可以发送详细消息。

  • JEP 359 - 记录- 引入新型记录的预览功能。

  • JEP 343 - 打包工具- 引入了基于 javapackager 的新打包器。

  • JEP 345 - NUMA 感知 G1 - G1 垃圾收集器现在支持 NUMA。

  • JEP 349 - JFR 事件流- 模块 jdk.jfr 中的包 jdk.jfr.consumer 已得到增强,可以异步订阅事件。

  • JEP 352 - 非易失性映射字节缓冲区- 添加新文件映射模式以引用非易失性内存,NVM。

  • JEP 363 - 删除了 CMS 垃圾收集器- 删除了 Java 9 中弃用的并发标记扫描 (CMS) 垃圾收集器。

  • JEP 347 - Pack200 工具和 API 已删除- pack200 和 unpack200 工具以及 java.util.jar 中的 Pack200 API 已被删除。

  • JEP 370 - 外部内存访问 API - 一种用于访问堆空间外部外部内存的新 API。

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

Java 14 - 环境设置

在线现场演示选项

我们已经在线设置了Java编程环境,以便您可以在线编译和执行所有可用的示例。它使您对所阅读的内容充满信心,并使您能够使用不同的选项验证程序。请随意修改任何示例并在线执行。

使用以下示例代码框右上角的“实时演示”选项尝试以下示例 -

public class MyFirstJavaProgram {
   public static void main(String []args) {
      System.out.println("Hello World");
   }
}

对于本教程中给出的大多数示例,您将在我们网站右上角的代码部分中找到“实时演示”选项,该选项将带您进入在线编译器。因此,请充分利用它并享受学习的乐趣。

本地环境设置

如果您想设置自己的 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”文件并在末尾添加以下行 -

    设置路径=%PATH%;C:\Program Files\java\jdk\bin

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

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

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

  • 导出 PATH=/path/to/java:$PATH'

流行的 Java 编辑器

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

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

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

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

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

Java 14 - 开关表达式

Java 12 向 Switch 语句引入了表达式,并将其作为预览功能发布。Java 13 添加了一个新的yield 构造来从 switch 语句返回值。在 Java 14 中,switch 表达式现在已成为一项标准功能。

  • 每个 case 块都可以使用yield 语句返回一个值。

  • 如果是枚举,则可以跳过默认情况。在其他情况下,需要默认情况。

例子

考虑以下示例 -

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: yield "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 APITester.java
$java APITester

输出

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

Java 14 - 文本块

Java 13 引入了文本块来处理多行字符串,如 JSON/XML/HTML 等,这是预览功能。在 Java 14 中,我们提供了文本块的第二次预览。现在文本块有以下增强功能 -

  • \ − 表示行结束,以防要开始新行。

  • \s - 表示单个空格。

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      String stringJSON = "{\r\n" 
         + "\"Name\" : \"Mahesh\"," 
         + "\"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 14 APITester.java

$java --enable-preview APITester

输出

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

Contains: true
indexOf: 15
Length: 45

Java 14 - instanceof 中的模式匹配

Java 14 引入了instanceof 运算符来拥有类型测试模式作为预览功能。类型测试模式有一个谓词来指定具有单个绑定变量的类型。

句法

if (obj instanceof String s) {
}

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      String message = "Welcome to Tutorialspoint";
      Object obj = message;
      // Old way of getting length
      if(obj instanceof String){
         String value = (String)obj;
         System.out.println(value.length());
      }
      // New way of getting length
      if(obj instanceof String value){
         System.out.println(value.length());
      }
   }
}

编译并运行程序

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

输出

25
25

Java 14 - 有用的 NullPointerException

Java 14 引入了 NullPointerException,其中包含有用的信息,以防 -XX:+ShowCodeDetailsInExceptionMessages 标志传递到 JVM。

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      String message = null;
      System.out.println(message.length());
   }   
}

老方法:编译并运行程序

$javac APITester.java
$java APITester

输出

Exception in thread "main" java.lang.NullPointerException
   at APITester.main(APITester.java:6)

新方式:使用新标志编译并运行程序

$javac APITester.java
$java -XX:+ShowCodeDetailsInExceptionMessages APITester

输出

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local1>" is null
   at APITester.main(APITester.java:6)

Java 14 - 打包工具

Java 14引入了一个新的打包工具,基于javapackager的jpackage。javapackager 是在 Java 8 中引入的,是 JavaFX 工具包的一部分。由于 JavaFX 从 Java 11 版本中分离出来,因此标准产品中不再提供此打包工具。

这个新工具的开发目的是为操作系统提供本机安装程序。例如,用于 Windows 的 msi/exe、用于 MacOS 的 pkg/dmg、用于 Linux 的 deb/rpm 等等。如果没有这个工具,开发人员通常会共享一个 jar 文件,用户必须在自己的 JVM 中运行该文件。

开发人员可以使用jlink将所需的JDK模块压缩为最小模块,并使用jpackage创建轻量级映像。

例子

考虑以下示例 -

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

输出

对于 Windows 可执行文件,您需要下载WiX Toolset v3.11.2(wix311-binaries.zip)并将工具包添加到您的路径。

创建 jar 并设置路径后,将 jar 放入名为 lib 的文件夹中,并运行以下命令来创建 Windows MSI 安装程序。

$jpackage --input lib --name APITester --main-jar APITester.jar --main-class APITester --type msi --java-options '--enable-preview'
WARNING: Using incubator modules: jdk.incubator.jpackage

Java 14 - NUMA 感知 G1

NUMA 代表非统一内存访问。它是一种内存架构,其中每个处理器核心都有自己的本地内存,但其他核心有权访问它。

并行 GC 与 -XX:+UseParallelGC 一起使用时可以在几年内实现 NUMA Aware。它提高了跨多个套接字运行单个 JVM 的配置的性能。在 Java 14 中,G1 得到了增强,可以更好地管理内存使用情况。

Z 垃圾收集器

Z 垃圾收集器是一种可扩展、低延迟的垃圾收集器。它首次作为实验性功能在 Java 11 中引入。它仅支持 Linux/x64。通过 Java 14,现在 ZGC 也可以移植到 Windows 和 Mac OS。目前,这也是一个实验性功能。从 Java 15 开始,它将成为标准 JDK 版本的一部分。

Java 14 - 其他增强功能

JEP 349 - JFR 事件流

JEP 349 增强了 JDK Flight Recorder 数据,以持续监控进程内和进程外应用程序。

直到 Java 13,为了使用 JFR 数据,用户需要开始录制、停止并将内容转储到磁盘,然后解析录制文件。这种方法非常适合应用程序分析,但也适用于监控。

现在,jdk.jfr.consumer 包已得到增强,可以异步订阅事件。使用此订阅,用户可以直接从磁盘存储库读取记录数据或流式读取,而无需转储记录文件。

JEP 352 - 非易失性映射字节缓冲区

借助此 JEP,Java 13 添加了新的 JDK 特定文件映射模式,以允许使用 FileChannel API 创建 MappedByteBuffer 实例并可以访问非易失性内存。非易失性内存或 NVM 是一种持久性内存,用于永久存储数据。

现在,MappedByteBufer API 支持直接内存更新,并提供持久性保证,这是块文件系统、日志日志、持久对象等更高级别 API 所需的,以实现持久数据类型。

JEP 370 - 外部内存访问 API

Java 14 现在允许 java 程序安全有效地访问 Java 堆之外的外部内存。早期的mapDB、memcached java 库提供了外部内存访问。该 JEP 旨在提供一个更清晰的 API,以无缝方式操作所有类型的外部内存(本机内存、持久内存、托管堆内存等)。无论外部内存类型如何,该 JEP 都会照顾 JVM 的安全性。垃圾收集/内存释放操作也应该明确提及。

该 API 基于三个主要抽象 MemorySegment、MemoryAddress 和 MemoryLayout,是访问堆内存和非堆内存的安全方法。

Java 14 - 弃用和删除

弃用

  • Solaris 和 SPARC 端口 (JEP 362) - 因为该 Unix 操作系统和 RISC 处理器在过去几年中并未得到积极开发。

  • ParallelScavenge + SerialOld GC 组合 (JEP 366) - 因为这是很少使用的 GC 算法组合,并且需要大量维护工作

搬迁

  • 并发标记清除 (CMS) 垃圾收集器 (JEP 363) - 此 GC 在 Java 9 中已弃用,并替换为 G1 作为默认 GC。还有其他高性能替代品,例如 ZDC、Shenandoah。这个GC保留了2年,供感兴趣的用户维护。由于没有主动维护,该 GC 现已从 Java 14 中完全删除。

  • Pack200 工具和 API (JEP 367) - 这些压缩库是在 Java 5 中引入的,在 Java 11 中已弃用。现在这些库已从 Java 14 中完全删除。