Java 11 中的重要特性

Java 11 于 2018 年 9 月推出,即 Java 10 发布六个月后。Java 10 是最后一个无需许可即可用于商业目的的 Java 版本。

虽然 Oracle JDK 不再免费,但我们始终可以从 Oracle 或其他提供商(例如 AdoptOpenJDK、Azul、IBM、Red Hat 等)下载 Open JDK 构建。在我看来,除非我们正在寻找有兴趣的企业级使用 支付支持费用后,我们可以使用 OpenJDK 并在必要时对其进行升级。


运行 Java 文件

要运行 Java 文件,我们首先使用 javac 命令对其进行编译。 但是使用 Java 11,我们可以使用单个 java 命令直接运行 Java 文件。

$ javac MyFirstJavaProgram.java
$ java MyFirstJavaProgram

我们不再需要使用上述过程。 相反,我们可以使用以下命令,它会给出相同的结果。

$ java MyFirstJavaProgram.java

新的 String 方法

Java 11 为 String 类引入了一些新方法。 下面解释了这些新方法。

isBlank() — 此方法用于检查字符串是否为空。 空字符串和只有空格的字符串被视为空白。

public class Demo
{
    public static void main(String[] args)
    {
        String s1 = "";
        String s2 = "    ";
        String s3 = "String";
        
        System.out.println("s1 is blank: " + s1.isBlank());
        System.out.println("s2 is blank: " + s2.isBlank());
        System.out.println("s3 is blank: " + s3.isBlank());
    }
}

Java 11 中的重要特性

lines() — 此方法使用行终止符拆分字符串并返回一个流。

import java.util.List;
import java.util.stream.Collectors;
public class Demo
{
    public static void main(String[] args)
    {
        String s = "This\n is\n a\n String";
        
        List<String> listOfLines = s.lines().collect(Collectors.toList());
        System.out.println(listOfLines);
    }
}

Java11 字符串 lines 方法

repeat() — 此方法用于复制或重复字符串。

public class Demo
{
    public static void main(String[] args)
    {
        String s = "String";
        
        System.out.println("String: " + s);
        System.out.println("String repeated twice: " + s.repeat(2));
        System.out.println("String repeated five times: " + s.repeat(5));
    }
}

Java11 字符串 repeat 方法

strip()stripLeading()stripTrailing() — 这些方法用于从字符串中删除空格。 它们与现有的 trim() 方法非常相似,但提供 Unicode 支持。

public class Demo
{
    public static void main(String[] args)
    {
        String s = "  string  ";
        System.out.println("$" + s + "$");
        System.out.println("$" + s.strip() + "$");
        System.out.println("$" + s.stripLeading() + "$");
        System.out.println("$" + s.stripTrailing() + "$");
    }
}

Java11 字符串 删除空格方法


基于嵌套的访问控制

以前的 Java 版本允许私有成员访问嵌套类(嵌套),但我们不能将它们与反射 API 一起使用。 Java 11 不再使用桥接方法,而是为反射 API 提供了 getNestHost()getNestMembers() 和 isNestmatOf() 方法。

public class Demo {
    private void privateMethod() {
        System.out.print("Private Method");
    }
    class NestedClass {
        public void callPrivateMethod() {
            privateMethod();
        }
    }
    public static void main(String[] args) {
        System.out.println(Demo.class.isNestmateOf(Demo.NestedClass.class)); //Demo class is nestmate of NestedClass
        System.out.println(Demo.NestedClass.class.isNestmateOf(Demo.class)); //NestedClass is nestmate of Demo class        
        System.out.println(Demo.NestedClass.class.getNestHost()); //Nest host of NestedClass
        System.out.println(Demo.class.getNestMembers()); //Nest host of Demo class        
    }
}

Java11 嵌套类


新的 File 方法

Java 11 使读写字符串变得更加容易。 为此,将 readString() 和 writeString() 静态方法添加到 Files 类。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Demo
{
    public static void main(String[] args) throws IOException
    {
        Path path = Files.createTempFile("temporaryFile",   ".txt");
        //写文件
        Files.writeString(path, "Hello World");
        //读文件
        String s = Files.readString(path);
        System.out.print(s);
    }
}

集合转数组

新的默认 toArray() 方法用于轻松地将集合转换为正确类型的数组。

import java.util.ArrayList;
import java.util.Arrays;
public class Demo
{
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(10);
        list.add(15);
        
        Integer[] intArr = list.toArray(Integer[]::new);
        System.out.print(Arrays.toString(intArr));
    }
}

not() 方法

Java 11 中的 Predicate 接口中添加了一个静态 not() 方法。顾名思义,此方法用于否定 Predicate。 not() 方法也可以与引用一起使用。

让我们使用这种方法创建两个执行相反任务的谓词。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Demo
{
    public static void main(String[] args) {
        Predicate<String> startWithZ = s -> s.charAt(0) == 'z';
        Predicate<String> doesNotStartWithZ = Predicate.not(startWithZ);
        
        List<String> list = Arrays.asList("za", "zq", "az", "aq", "zz");
        List<String> strsStartingWithZ = list.stream()
                                .filter(startWithZ)
                                .collect(Collectors.toList());
        List<String> strsNotStartingWithZ = list.stream()
                .filter(doesNotStartWithZ)
                .collect(Collectors.toList());
        
        System.out.println(strsStartingWithZ);
        System.out.println(strsNotStartingWithZ);
    }
}

Java11 not 方法


HTTP Client 客户端

HTTP 客户端 API 最初是在 Java 9 中引入的,并在 Java 10 中进行了更新。它在 Java 11 版本中作为标准功能提供。 新的 API 性能更好,同时兼容 HTTP/1.1 和 HTTP/2。 该 API 还提供对 WebSockets 的支持。


Lambda 的局部变量语法

Java 11 增加了对 lambda 表达式的 Local-Variable 语法的支持。 Lambda 可以推断类型,但使用 var 关键字允许我们使用带有参数的 @NotNull 或 @Nullable 等注解。

(@NotNull var str) -> "$" + str

动态类文件常量

在 Java 11 中,Java 类文件格式支持一种新的常量池形式,称为 CONSTANT_Dynamic。 这会将创建委托给引导方法。 引入此功能是为了通过创建一个新的常量池形式来降低创建新形式的可实现类文件常量的成本,该形式将使用适当的用户定义行为进行参数化。 此功能大大提高了性能。


改进的 Aarch64 Intrinsic

Intrinsic 是由编译器以某种特殊方式处理的函数。 它们利用特定于 CPU 架构的汇编代码来提高性能。

Java 11 改进和优化了 AArch64(或 ARM64)处理器上现有的字符串和数组。 Java 11 还为“java.lang.Math”的 sin、cos 和 log 方法添加了新的 Intrinsic 函数。


Epsilon 垃圾收集器

Java 11 引入了一个名为 Epsilon 的无操作(No-Op)垃圾收集器。 这是一个实验性功能。 它被称为 No-Op 垃圾收集器,因为它会分配内存但永远不会收集任何垃圾。 我们可以用它来模拟 Out-Of-Memory 错误。 以下是它的一些用例。

  • 性能测试
  • 内存压力测试
  • 虚拟机接口测试和
  • 寿命极短的工作
  • 最后丢弃延迟和吞吐量改进

使用以下命令启用 Epsilon GC。

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

Java Flight Recorder

Java Flight Recorder(简称JFR)用于收集应用程序的分析数据。 它过去仅可用于商业用途,但现在在 OpenJDK 11 下开源。我们可以将其用于生产应用程序,因为它的开销很小(低于 1%)。 它将数据记录在一个 JFR 文件中,我们可以使用 JDK Mission Control 工具来分析收集到的信息。 使用以下命令开始 180 秒 JFR 录制并将数据存储在 demo.jfr 文件中。

-XX:StartFlightRecording=duration=180s,settings=profile,filename=demo.jfr 

不推荐使用的 Java EE 和 CORBA 模块

Java EE 和 COBRA 的一些模块在 Java 9 中已弃用。它们现在已从 Java 11 中完全删除。以下包和工具不再是 Java 11 的一部分。但是,它们仍可在第三方网站上使用。

  • java.xml.ws
  • java.xml.bind
  • java.activation
  • java.xml.ws.annotation
  • java.corba
  • java.transaction
  • java.se.ee
  • wsgen 和 wsimport
  • schemagen 和 xjc
  • idlj, orbd, servertool, 和 tnamesrv