Java 12 - 快速指南


Java 12 - 概述

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

Java 12 是非 LTS 版本。

新功能

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

  • JVM 更改- JEP 189、JEP 346、JEP 344 和 JEP 230。

  • Switch Expressions - 允许切换使用 lambda 表达式的预览功能。

  • File.mismatch() 方法- 通过不匹配方法可以轻松进行文件比较。

  • 紧凑的数字格式- 数字可以轻松格式化,如 2K、3M 等。

  • Stream API 中的 Teeing Collector - 多个收集器上的合并运算符。

  • 字符串新方法- 引入了四种新方法来格式化字符串。

  • JEP 334 - 引入了 JVM 常量 API。

  • JEP 305 - 允许实例匹配模式的预览功能。

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

Java 12 - 环境设置

本地环境设置

如果您想设置自己的 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,可以从https://www.netbeans.org/index.html下载。

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

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

Java 12 - 开关表达式

Java 12 向 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) {

      String result = switch (day) {
         case "Monday", "Tuesday", "Wednesday","Thursday", "Friday" -> "Weekday";
         case "Saturday", "Sunday" -> "Weekend";
         default -> {
            break "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 12 APITester.java

$java --enable-preview APITester

输出

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

Java 12 - 文件不匹配方法

Java 12 引入了一种使用以下语法比较两个文件的简单方法 -

public static long mismatch(Path path1, Path path2) throws IOException

在哪里

  • 如果没有不匹配,则返回 1L,否则返回第一个不匹配的位置。

  • 如果文件大小不匹配或字节内容不匹配,则会考虑不匹配。

考虑以下示例 -

ApiTester.java

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class APITester {
   public static void main(String[] args) throws IOException {
      Path path1 = Files.createTempFile("file1", ".txt");
      Path path2 = Files.createTempFile("file2", ".txt");

      Files.writeString(path1, "tutorialspoint");
      Files.writeString(path2, "tutorialspoint");

      long mismatch = Files.mismatch(path1, path2);

      if(mismatch > 1L) {
         System.out.println("Mismatch occurred in file1 and file2 at : " + mismatch);
      }else {
         System.out.println("Files matched");
      }

      System.out.println();

      Path path3 = Files.createTempFile("file3", ".txt");
      Files.writeString(path3, "tutorialspoint Java 12");

      mismatch = Files.mismatch(path1, path3);

      if(mismatch > 1L) {
         System.out.println("Mismatch occurred in file1 and file3 at : " + mismatch);
      }else {
         System.out.println("Files matched");
      }

      path1.toFile().deleteOnExit();
      path2.toFile().deleteOnExit();
      path3.toFile().deleteOnExit();
   }
}

输出

Files matched

Mismatch occurred in file1 and file3 at : 14

Java 12 - 紧凑数字格式

Java 12 引入了紧凑格式,我们可以将长数字的小数、货币或百分比格式化为短格式或长格式。例如1000到1K。以下语法显示了用法 -

NumberFormat formatter = NumberFormat.getCompactNumberInstance(
   Locale.US, NumberFormat.Style.SHORT);
   System.out.println(formatter.format(1000)
);

考虑以下示例 -

ApiTester.java

import java.text.NumberFormat;
import java.util.Locale;

public class APITester {
   public static void main(String[] args) {
      NumberFormat formatter = NumberFormat.getCompactNumberInstance(
         Locale.US, NumberFormat.Style.LONG);

      System.out.println(formatter.format(1000));
      System.out.println(formatter.format(1000000));

      formatter = NumberFormat.getCompactNumberInstance(
         Locale.US, NumberFormat.Style.SHORT);

      System.out.println(formatter.format(1000));
      System.out.println(formatter.format(1000000));
   }
}

输出

1 thousand
1 million
1K
1M

Java 12 - Tee 收集器

Java 12 向 Collectors 引入了一种新方法,可以对集合执行两种不同的操作,然后合并结果。以下是 teeing 方法的语法 -

Collector<T, ?, R> teeing(
   Collector<? super T, ?, R1> downstream1,
   Collector<? super T, ?, R2> downstream2, 
   BiFunction<? super R1, ? super R2, R> merger
)

在这里,我们对集合执行不同的函数,然后使用合并 BiFunction 合并结果。

考虑以下示例 -

ApiTester.java

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class APITester {
   public static void main(String[] args) {
      double mean
         = Stream.of(1, 2, 3, 4, 5, 6, 7)
            .collect(Collectors.teeing(
               Collectors.summingDouble(i -> i), Collectors.counting(),
               (sum, n) -> sum / n));

      System.out.println(mean);
   }
}

输出

4.0

Java 12 - 字符串方法

Java 12 为 String 引入了以下新方法以方便格式化。

缩进(n)方法

根据传递的参数调整每行字符串的缩进。

用法

string.indent(n)
  • n > 0 - 在每行的开头插入空格。

  • n < 0 - 删除每行开头的空格。

  • n < 0 和 n < 可用空格- 删除每行的所有前导空格。

  • n = 0 - 没有变化。

Transform(Function<? super String,​? extends R> f) 方法

转换字符串以给出 R 形式的结果。

用法

String transformed = text.transform(value -> new StringBuilder(value).reverse().toString());

可选的<String>描述Constable()方法

返回包含 String 实例描述的可选对象。

用法

Optional<String> optional = message.describeConstable();

resolveConstantDesc​(MethodHandles.Lookup查找)方法

返回给定字符串的描述符实例字符串。

用法

String constantDesc = message.resolveConstantDesc(MethodHandles.lookup());

考虑以下示例 -

ApiTester.java

import java.lang.invoke.MethodHandles;
import java.util.Optional;

public class APITester {
   public static void main(String[] args) {
      String str = "Welcome \nto Tutorialspoint!";
      System.out.println(str.indent(0));
      System.out.println(str.indent(3));

      String text = "Java";
      String transformed = text.transform(value -> new StringBuilder(value).reverse().toString());
      System.out.println(transformed);

      Optional<String> optional = text.describeConstable();
      System.out.println(optional);

      String cDescription = text.resolveConstantDesc(MethodHandles.lookup());
      System.out.println(cDescription);
   }
}

输出

Welcome 
to Tutorialspoint!

   Welcome 
   to Tutorialspoint!

avaJ
Optional[Java]
Java

Java 12 - 垃圾收集增强功能

Java 12 对其垃圾收集算法引入了多项增强功能。

JEP 189 – Shenandoah:低暂停时间垃圾收集器(实验)

引入了实验性低暂停时间垃圾收集器 Shenandoah 来减少 GC 暂停时间。它与运行的 java 线程并行工作。这有助于减少 GC 对堆大小的依赖并使其保持一致。现在,对于 2 MB 和 2 GB 堆空间,垃圾收集暂停时间将相似。

Shenandoah 预计将成为 Java 15 主要 JAVA 版本的一部分。

JEP 346 – 立即返回未使用的提交内存

在 Java 12 中,如果应用程序处于非活动状态,G1 将处理 Java 堆空间,并可能将内存释放给操作系统。这种先发制人的Behave可以节省并释放内存。

JEP 344:可流产的混合收藏

在 Java 12 中,G1 效率得到了提高。现在,如果 G1 混合集合超过定义的暂停限制,则它们会被中止。现在混合集合分为强制集合和可选集合。G1收集器可以优先考虑强制集来检查暂停时间目标。

Java 12 - 微基准测试

Java 12 对其垃圾收集算法引入了多项增强功能。

JEP 189 – Shenandoah:低暂停时间垃圾收集器(实验)

引入了实验性低暂停时间垃圾收集器 Shenandoah 来减少 GC 暂停时间。它与运行的 java 线程并行工作。这有助于减少 GC 对堆大小的依赖并使其保持一致。现在,对于 2 MB 和 2 GB 堆空间,垃圾收集暂停时间将相似。

Shenandoah 预计将成为 Java 15 主要 JAVA 版本的一部分。

JEP 346 – 立即返回未使用的提交内存

在 Java 12 中,如果应用程序处于非活动状态,G1 将处理 Java 堆空间,并可能将内存释放给操作系统。这种先发制人的Behave可以节省并释放内存。

JEP 344:可流产的混合收藏

在 Java 12 中,G1 效率得到了提高。现在,如果 G1 混合集合超过定义的暂停限制,则它们会被中止。现在混合集合分为强制集合和可选集合。G1收集器可以优先考虑强制集来检查暂停时间目标。