Java 11 新特性

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

Java 11 于 2018 年 9 月发布,它为平台引入了许多新功能和变化。本实验将引导你开始使用 Java 11 并探索其新特性。

环境设置

首先,确保你的系统上已经安装了 JDK 11。你可以通过在终端中运行以下命令来验证:

java -version

如果尚未安装 Java 11,你可以从 Oracle 网站下载,或者使用包管理器如 apt-getyum 进行安装。

安装好 JDK 后,使用以下命令创建一个 Java 文件:

mkdir -p ~/project && cd ~/project
touch MyFirstJavaProgram.java

Java 文件创建完成后,用你喜欢的文本编辑器打开它。

touch MyFirstJavaProgram.java

运行 Java 文件

在 Java 11 之前,我们需要先使用 javac 命令编译 Java 文件,然后再使用 java 命令运行它。而在 Java 11 中,我们可以直接使用 java 命令运行 Java 文件。

MyFirstJavaProgram.java 文件中,添加以下代码:

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

保存文件后,使用以下命令运行它:

java MyFirstJavaProgram.java

你应该会在控制台中看到 "Hello, Java 11!" 的输出。

新的字符串方法

Java 11 为 String 类引入了一些新方法。在这一步中,我们将探索这些新方法。

isBlank() 方法

isBlank() 方法用于检查字符串是否为空。空字符串或仅包含空格的字符串被视为空白。

MyFirstJavaProgram.java 文件中,添加以下代码:

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());

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会看到以下输出:

s1 is blank: true
s2 is blank: true
s3 is blank: false
strip(), stripLeading(), 和 stripTrailing() 方法

strip()stripLeading()stripTrailing() 方法用于去除字符串中的空格。它们与现有的 trim() 方法类似,但提供了对 Unicode 的支持。

MyFirstJavaProgram.java 文件中,添加以下代码:

String s = "   String   ";
System.out.println("$" + s + "$");
System.out.println("$" + s.strip() + "$");
System.out.println("$" + s.stripLeading() + "$");
System.out.println("$" + s.stripTrailing() + "$");

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会看到以下输出:

$   String   $
$String$
$String   $
$   String$

基于嵌套的访问控制

Java 11 引入了一项新特性,允许我们使用反射 API(Reflection API)访问嵌套类的私有成员。在这一步中,我们将探索这一新特性。

MyFirstJavaProgram.java 文件中,添加以下代码:

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));
        System.out.println(Demo.NestedClass.class.isNestmateOf(Demo.class));
        System.out.println(Demo.NestedClass.class.getNestHost());
        System.out.println(Arrays.toString(Demo.class.getNestMembers()));
    }
}

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会看到以下输出:

true
true
class Demo
[class MyFirstJavaProgram$Demo$NestedClass]

新的文件方法

Java 11 为 Files 类引入了一些新方法,使得读写字符串变得更加简单。在这一步中,我们将探索这些新方法。

MyFirstJavaProgram.java 文件中,添加以下代码:

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");
        //Writing to the file
        Files.writeString(path, "Hello World");
        //Reading from the file
        String s = Files.readString(path);
        System.out.print(s);
    }
}

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会看到以下输出:

Hello World

集合转换为数组

Java 11 引入了一个新的默认 toArray() 方法,使得将集合转换为正确类型的数组变得更加容易。

MyFirstJavaProgram.java 文件中,添加以下代码:

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));
    }
}

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会看到以下输出:

[5, 10, 15]

not() 方法

Java 11 在 Predicate 接口中引入了一个新的 not() 方法,用于对谓词(Predicate)进行取反操作。在这一步中,我们将探索这一特性。

MyFirstJavaProgram.java 文件中,添加以下代码:

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);
    }
}

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会看到以下输出:

[za, zq, zz]
[az, aq]

HTTP 客户端

HTTP 客户端 API 在 Java 9 中引入,并在 Java 11 中成为标准。在这一步中,我们将探索如何使用新的 HTTP 客户端 API。

MyFirstJavaProgram.java 文件中,添加以下代码:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class Demo {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://www.google.com"))
                .GET()
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
        System.out.println(response.body());
    }
}

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会在控制台中看到 Google 主页的 HTML 代码。

Lambda 表达式的局部变量语法

Java 11 引入了 var 关键字,允许我们在 Lambda 表达式中使用局部变量语法。在这一步中,我们将探索这一新特性。

MyFirstJavaProgram.java 文件中,添加以下代码:

import java.util.function.Predicate;

public class Demo {
    public static void main(String[] args) {
        Predicate<String> startsWithZ = (@NotNull var str) -> str.charAt(0) == 'z';
        System.out.println(startsWithZ.test("zoo"));
    }
}

保存文件后,使用以下命令运行它:

javac MyFirstJavaProgram.java
java MyFirstJavaProgram

你应该会在控制台中看到 true 被打印出来。

Epsilon 垃圾回收器

Java 11 引入了一个名为 Epsilon 垃圾回收器的实验性功能,它分配内存但从不回收垃圾。在这一步中,我们将探索这一实验性功能。

MyFirstJavaProgram.java 文件中,添加以下代码:

public class Demo {
    public static void main(String[] args) {
        byte[] b = new byte[1024 * 1024 * 1024];
        System.out.println("Allocated 1GB of memory");
    }
}

保存文件后,使用以下命令运行它:

java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC MyFirstJavaProgram.java

你应该会在控制台中看到 "Allocated 1GB of memory" 被打印出来,随后程序以代码 0 退出。

总结

在本实验中,你学习了 Java 11 引入的新特性,包括新的 String 方法、基于嵌套的访问控制、新的文件方法等。你还学习了如何使用新的 HTTP 客户端 API 和 Epsilon 垃圾回收器。现在你应该对 Java 11 及其功能有了更深入的理解。

您可能感兴趣的其他 Java 教程