Java 15 - 快速指南


Java 15 - 概述

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

Java 15 是非 LTS 版本。

新功能

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

  • JEP 360 - 密封类- 提供对继承的细粒度控制。

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

  • JEP 375 - 模式匹配类型检查- 增强 Java 14 的现有模式匹配预览功能。

  • JEP 371 - 隐藏类- 允许运行时创建不可发现的类。

  • JEP 384 - 记录- 增强 Java 14 中引入的新型记录的预览功能。

  • JEP 383 - 外部内存访问 API - 增强 java 14 的孵化功能。

  • JEP 377, 379 - 垃圾收集器- ZDC 和 Shenandoah 垃圾收集器现在是标准 API 的一部分。

  • JEP 339 - 爱德华兹曲线数字签名算法 (EdDSA) - 加密签名现在使用 EdDSA 实现。

  • JEP 373 - 重新实现旧版 DatagramSocket API - java.net.DatagramSocket 和 java.net.MulticastSocket API 的旧版实现被替换为更简单、更现代、易于维护和调试的实现。

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

Java 15 - 环境设置

在线现场演示选项

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

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

例子

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

输出

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 15 - 密封类

Java 15 引入了密封类作为预览功能,它提供了对继承的细粒度控制。以下是密封类需要考虑的要点 -

  • 密封类是使用 seal 关键字声明的。

  • 密封类允许使用 Permits 关键字声明哪个类可以是子类型。

  • 扩展密封类的类必须声明为密封类、非密封类或最终类。

  • 密封类有助于在继承中创建有限且可确定的类层次结构。

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      Person manager = new Manager(23, "Robert");
      manager.name = "Robert";
      System.out.println(getId(manager));
   }
   public static int getId(Person person) {
      if (person instanceof Employee) {
         return ((Employee) person).getEmployeeId();
      } 
      else if (person instanceof Manager) {
         return ((Manager) person).getManagerId();
      }
      return -1;
   }
}
abstract sealed class Person permits Employee, Manager {
   String name;
   String getName() {
      return name;
   }
}
final class Employee extends Person {
   String name;
   int id;
   Employee(int id, String name){
      this.id = id;
      this.name = name;
   }
   int getEmployeeId() {
      return id;
   }
}
non-sealed class Manager extends Person {
   int id;
   Manager(int id, String name){
      this.id = id;
      this.name = name;
   }
   int getManagerId() {
      return id;
   }
}

编译并运行程序

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

输出

23

Java 15 - instanceof 中的模式匹配

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

句法

if (person instanceof Employee e) {
   return e.getEmployeeId();
}

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      Person manager = new Manager(23, "Robert");
      manager.name = "Robert";
      System.out.println(getId(manager));
   }
   public static int getId(Person person) {
      if (person instanceof Employee e) {
         return e.getEmployeeId();
      } 
      else if (person instanceof Manager m) {
         return m.getManagerId();
      }
      return -1;
   }
}
abstract sealed class Person permits Employee, Manager {
   String name;
   String getName() {
      return name;
   }
}
final class Employee extends Person {
   String name;
   int id;
   Employee(int id, String name){
      this.id = id;
      this.name = name;
   }
   int getEmployeeId() {
      return id;
   }
}
non-sealed class Manager extends Person {
   int id;
   Manager(int id, String name){
      this.id = id;
      this.name = name;
   }
   int getManagerId() {
      return id;
   }
}

编译并运行程序

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

输出

23

Java 15 - 文本块

Java 13 引入了文本块来处理多行字符串,如 JSON/XML/HTML 等,这是预览功能。在 Java 14 中,我们提供了文本块的第二次预览。现在,文本块不再是预览功能,而是标准产品的一部分。

例子

考虑以下示例 -

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

输出

{
   "Name" : "Mahesh","RollNO" : "32"
}
{
   "name" : "Mahesh",   "RollNO" : "32"
}
Contains: true
indexOf: 15
Length: 45

Java 15 - 记录

Java 14 引入了新的类类型记录作为预览功能,以方便创建不可变数据对象。Java 15 进一步增强了记录类型。它仍然是预览功能。

  • 记录对象具有隐式构造函数,所有参数都作为字段变量。

  • 记录对象对于每个字段变量都有隐式字段 getter 方法。

  • 记录对象对于每个字段变量都有隐式字段设置方法。

  • Record 对象具有 hashCode()、equals() 和 toString() 方法的隐式合理实现。

  • 在 Java 15 中,无法在记录中声明本机方法。

  • 在 Java 15 中,记录的隐式字段不是最终的,使用反射进行修改将抛出 IllegalAccessException。

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      StudentRecord student = new StudentRecord (1, "Julie", "Red", "VI", 12);
      System.out.println(student.id());
      System.out.println(student.name());
      System.out.println(student);
   }
}
record StudentRecord(int id, 
   String name, 
   String section, 
   String className,
   int age){}

编译并运行程序

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

输出

1
Julie
StudentRecord[id=1, name=Julie, section=Red, className=VI, age=12]

Java 15 - 密封接口记录

因为记录默认是最终的并且可以扩展接口。我们可以定义密封接口并让record实现它们以更好地管理代码。

例子

考虑以下示例 -

ApiTester.java

public class APITester {
   public static void main(String[] args) {
      Person employee = new Employee(23, "Robert");
      System.out.println(employee.id());
	   System.out.println(employee.name());
   }
}
sealed interface Person permits Employee, Manager {
   int id();
   String name();
}
record Employee(int id, String name) implements Person {}
record Manager(int id, String name) implements Person {}

编译并运行程序

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

输出

23
Robert

Java 15 - 隐藏类

Java 15 引入了隐藏类,这些类不能被其他类字节码直接使用。这些隐藏类旨在由在运行时生成类并通过反射使用它们的框架使用。

隐藏类被定义为基于嵌套的访问控制上下文的成员,并且可以独立于其他类来卸载它。

该提案 JEP 371 旨在通过提供标准 API 来定义不可发现且生命周期有限的隐藏类,从而改进 JVM 上的所有语言。JDK框架或外部框架可以动态生成类,这些类可以生成隐藏类。

JVM 语言严重依赖动态类生成来实现灵活性和效率。

目标

以下是此增强功能的目标列表。

  • 框架应该能够将类定义为框架的不可发现的实现细节,这些类既不能链接到其他类,也不能使用反射来发现。

  • 使用不可发现的类扩展访问控制嵌套。

  • 积极卸载隐藏类,这将帮助框架根据需要定义尽可能多的隐藏类,而不会降低性能。

  • 弃用非标准 API,misc.Unsafe::defineAnonymousClass,将在未来版本中删除。

Java 15 - 垃圾收集器

Java 15 使 ZGC(Z 垃圾收集器)成为标准功能。在 Java 15 之前,这是一个实验性功能。它是低延迟、高度可扩展的垃圾收集器。

ZGC 在 Java 11 中作为实验性功能引入,因为开发者社区认为它太大而无法提前发布。从那时起,对垃圾收集进行了很多改进,例如 -

  • 并发类卸载

  • 取消未使用内存的提交

  • 支持类数据共享

  • NUMA 意识

  • 多线程堆预接触

  • 最大堆大小限制为 4 TB 到 16 TB。

ZGC 具有高性能,即使在机器学习应用等海量数据应用中也能高效工作。它确保处理数据时不会因垃圾收集而长时间暂停。它支持 Linux、Windows 和 MacOS。

Shenandoah 低暂停时间垃圾收集器现已脱离实验阶段。它已被引入到 JDK 12 中,从 java 15 开始,它是标准 JDK 的一部分。

Java 15 - 其他更改

JEP 383 - 外部内存访问 API

Java 14 允许 Java 程序安全高效地访问 Java 堆之外的外部内存。早期的mapDB、memcached、ignite java库提供了外部内存访问。它是一个更干净的 API,可以无缝地操作所有类型的外部内存(本机内存、持久内存、托管堆内存等)。无论外部内存类型如何,它还负责 JVM 的安全。垃圾收集/内存释放操作也应该明确提及。

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

Java 15 继续孵化此功能,并为 API 添加了新的改进。

JEP 339 - 爱德华曲线数字签名算法(EdDSA)

Edwards-Curve数字签名算法,EdDSA是一种先进的椭圆曲线方案,比JDK中现有的签名方案更好。与其他签名方案相比,它提高了安全性和性能。它受到 OpenSSL、BoringSSL 等流行加密库的支持。EdDSA 仅在 SunEC 提供商的 java 15 中实现。

JEP 373 - 重新实现旧版 DatagramSocket API

java.net.DatagramSocket 和 java.net.MulticastSocket API 的旧实现已被替换为更简单、更现代、易于维护和调试的实现。

java.net.datagram.Socket 和 java.net.MulticastSocket 当前的实现是从 1.0 开始就在 jdk 中,IPv6 仍在开发中。该 JEP 的目标是取代 MulticastSocket 的当前实现,后者以难以维护的方式协调了 IPv4 和 IPv6。

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 中完全删除。

Java 15 - 其他增强功能

JEP 383 - 外部内存访问 API

Java 14 允许 Java 程序安全高效地访问 Java 堆之外的外部内存。早期的mapDB、memcached、ignite java库提供了外部内存访问。它是一个更干净的 API,可以无缝地操作所有类型的外部内存(本机内存、持久内存、托管堆内存等)。无论外部内存类型如何,它还负责 JVM 的安全。垃圾收集/内存释放操作也应该明确提及。

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

Java 15 继续孵化此功能,并为 API 添加了新的改进。

  • 引入 VarHandle API 来自定义内存访问 var 句柄。

  • 使用 Spliterator 接口支持内存段的并行处理。

  • 映射内存段支持增强。

  • 本机调用地址可以被操纵和取消引用。

JEP 339 - 爱德华曲线数字签名算法(EdDSA)

Edwards-Curve数字签名算法,EdDSA是一种先进的椭圆曲线方案,比JDK中现有的签名方案更好。与其他签名方案相比,它提高了安全性和性能。它受到 OpenSSL、BoringSSL 等流行加密库的支持。EdDSA 仅在 SunEC 提供商的 java 15 中实现。

JEP 373 - 重新实现旧版 DatagramSocket API

java.net.DatagramSocket 和 java.net.MulticastSocket API 的旧实现已被替换为更简单、更现代、易于维护和调试的实现。

java.net.datagram.Socket 和 java.net.MulticastSocket 的当前实现是从 1.0 开始就在 jdk 中,IPv6 仍在开发中。此 JEP 的目标是替换 MulticastSocket 的当前实现,后者以难以实现的方式协调了 IPv4 和 IPv6维持。

标准文本块

Java 15 中的文本块不再是预览版。现在它们是标准 JDK 的一部分。

有用的空指针异常

Java 15 中现在默认启用有用的 NullPointerException。

Java 15 - 弃用和删除

弃用

以下功能已弃用,并计划在未来版本中删除。

  • 偏向锁定- 默认情况下禁用偏向锁定,并且不推荐使用所有相关的命令行选项。JDK 社区正在寻求检查是否需要难以维护偏向锁定的遗留同步机制。HotSpot虚拟机中使用偏向锁来减少无竞争锁的开销。

  • RMI 激活- 自 Java 8 以来,RMI 激活是可选部分,并且是 RMI 的过时部分。它增加了持续的维护成本。

搬迁

以下功能已被删除。

  • Nashorn JavaScript 引擎- Java 8 中引入的 Nashorn JavaScript 引擎现已删除。随着 GraalVM 和其他 VM 技术的出现,Nashorn 不再在 Java 生态系统中使用。

  • Solaris/SPARC 端口- 删除了 Java 14 中已弃用的源代码和对 Solaris/SPARC、Solaris/x64 和 Linux/SPARC 端口的支持。Solaris 和 SPARC 已被 Linux 操作系统和 Intel 处理器取代。因此,删除他们的代码将有助于贡献者专注于开发要添加到平台的新功能。