Skip to content

JDK 11 其他特性

JDK 11 是继 JDK 8 之后最重要的 LTS 版本。它不仅引入了 ZGC 和 HTTP Client,还带来了大量实用改进。

String 新方法(JDK 11)

String 类新增了 5 个实用方法:

java
public class StringMethodsDemo {

    public static void main(String[] args) {
        // isBlank() - 判断是否空白
        System.out.println("".isBlank());           // true
        System.out.println("   ".isBlank());        // true
        System.out.println("hello".isBlank());       // false

        // lines() - 按行分割
        String multiline = "line1\nline2\nline3";
        multiline.lines().forEach(System.out::println);

        // strip() - 去空白(Unicode)
        System.out.println("  hello  ".strip());    // "hello"
        // 比 trim() 更好,能处理 Unicode 空白字符

        // stripLeading() / stripTrailing()
        System.out.println("  hello  ".stripLeading());   // "hello  "
        System.out.println("  hello  ".stripTrailing());  // "  hello"

        // repeat() - 重复
        System.out.println("na ".repeat(3) + "Batman!");  // "na na na Batman!"
    }
}

集合 toArray() 增强

java
import java.util.*;

public class ToArrayDemo {

    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");

        // 以前的方式
        String[] arr1 = list.toArray(new String[0]);

        // JDK 11+:更简洁
        String[] arr2 = list.toArray(String[]::new);

        // JDK 16+:toList() 直接收集
        List<String> list2 = list.stream().filter(s -> s.length() > 1).toList();
    }
}

Predicate.not() 方法

java
import java.util.function.*;
import java.util.*;

public class NotPredicateDemo {

    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "", "Bob", "  ", "Charlie");

        // 以前:negate()
        List<String> result1 = names.stream()
            .filter(s -> !s.isBlank())
            .toList();

        // JDK 11+:Predicate.not()
        List<String> result2 = names.stream()
            .filter(Predicate.not(String::isBlank))
            .toList();

        // 好处:比匿名类写法更清晰
        List<String> result3 = names.stream()
            .filter(Predicate.not(s -> s.length() > 100))  // 更易读
            .toList();

        System.out.println(result2);
    }
}

Files.readString() / Files.writeString()

java
import java.nio.file.*;

public class FileReadWriteDemo {

    public static void main(String[] args) throws Exception {
        Path file = Path.of("test.txt");

        // JDK 11+:读取整个文件为字符串
        String content = Files.readString(file);
        System.out.println(content);

        // JDK 11+:写入字符串到文件
        Files.writeString(file, "Hello, Java!");
        
        // JDK 11+:写入字符串,指定编码
        Files.writeString(file, "你好,Java!", java.nio.charset.StandardCharsets.UTF_8);
        
        // JDK 12+:写入字符串,配置选项
        Files.writeString(file, "Overwrite",
            java.nio.file.StandardOpenOption.TRUNCATE_EXISTING);
    }
}

局部变量类型推断增强(JDK 11)

java
import java.util.function.*;

public class VarLambdaDemo {

    public static void main(String[] args) {
        // JDK 11+:Lambda 参数可以使用 var
        BiFunction<Integer, Integer, Integer> add = (var a, var b) -> a + b;
        System.out.println(add.apply(3, 5));  // 8

        // 以前:必须全部省略类型或全部写类型
        // BiFunction<Integer, Integer, Integer> old = (Integer a, Integer b) -> a + b;
        
        // 混用不行
        // (var a, Integer b) -> a + b  // ❌ 编译错误
    }
}

String.transform()

java
import java.util.*;

public class TransformDemo {

    public static void main(String[] args) {
        // JDK 12+:String.transform()
        String result = "hello"
            .transform(String::toUpperCase)
            .transform(s -> s + " WORLD")
            .transform(s -> "[" + s + "]");

        System.out.println(result);  // [HELLO WORLD]

        // 实际应用:链式处理
        String csv = "  Alice , 25 , Beijing  ";
        String[] fields = csv
            .transform(String::trim)
            .transform(s -> s.replaceAll("\\s+", ""))
            .split(",");

        System.out.println(Arrays.toString(fields));  // [Alice, 25, Beijing]
    }
}

Collection.toArray(IntFunction)

java
import java.util.*;
import java.util.function.*;

public class ToArrayFunctionDemo {

    public static void main(String[] args) {
        List<String> list = List.of("a", "bb", "ccc");

        // JDK 12+:指定数组生成器
        String[] arr = list.toArray(String[]::new);
        System.out.println(Arrays.toString(arr));  // [a, bb, ccc]

        // 以前需要这样
        String[] arr2 = list.toArray(new String[0]);

        // 场景:从 Set 获取特定类型数组
        Set<Integer> numbers = Set.of(1, 2, 3);
        int[] intArray = numbers.stream()
            .mapToInt(Integer::intValue)
            .toArray();
    }
}

String.align()

java
public class AlignDemo {

    public static void main(String[] args) {
        // JDK 16+:文本对齐
        String text = "Hi";

        System.out.println(text.align(10, Alignment.CENTER));  // "    Hi    "
        System.out.println(text.align(10, Alignment.LEFT));    // "Hi        "
        System.out.println(text.align(10, Alignment.RIGHT));  // "        Hi"

        // JDK 12+:indent()
        System.out.println("hello".indent(4));   // "    hello"
        System.out.println("  hello".indent(-2)); // "hello"
    }
}

新的运行时选项

单一源代码文件启动(JDK 11+)

bash
# JDK 11+:直接运行 .java 文件
java Hello.java

# JDK 11 之前:必须先 javac 再 java
javac Hello.java
java Hello

移除 Java EE 和 CORBA 模块(JDK 11)

bash
# JDK 9-10:Java EE 模块在 classpath 上
java -cp ".:$JAVA_HOME/lib/javaws.jar" MyApp.java

# JDK 11+:这些模块被移除
# 如果需要,使用 Maven 依赖
# <dependency>
#     <groupId>javax.xml.bind</groupId>
#     <artifactId>jaxb-api</artifactId>
#     <version>2.3.1</version>
# </dependency>

Unicode 10 支持(JDK 10+)

java
// JDK 10+ 支持 Unicode 10.0(之前是 6.0)
// 新增了 emoji 字符等
String emoji = "😀 😀";
System.out.println(emoji.codePointCount(0, emoji.length()));  // 2

性能改进

启动速度

bash
# JDK 11 改进了 JIT 编译
# 应用启动速度更快

垃圾收集器改进

bash
# JDK 11 的 GC 改进:
# - Epsilon GC(无操作 GC):用于短生命周期程序
java -XX:+UseEpsilonGC -Xms256m -Xmx256m -jar short-app.jar

# - ZGC 实验支持(JDK 11),JDK 15 成为正式版
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar app.jar

HTTP Client 正式版(JDK 11)

java
// JDK 9 预览,JDK 11 正式版
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(
    HttpRequest.newBuilder().uri(URI.create("https://api.example.com")).GET().build(),
    HttpResponse.BodyHandlers.ofString()
);

新增 API

Stream.takeWhile / dropWhile(JDK 9)

java
List<Integer> result = Stream.of(1, 2, 3, 4, 1, 2)
    .takeWhile(n -> n < 4)  // 取到条件不满足为止
    .toList();
// [1, 2, 3]

Optional.or()(JDK 9)

java
Optional<String> opt = Optional.empty()
    .or(() -> Optional.of("default"));
System.out.println(opt.orElse("nothing"));  // "default"

ProcessHandle(JDK 9)

java
ProcessHandle.current()
    .info()
    .command()
    .ifPresent(System.out::println);

小结

JDK 11 是个重磅 LTS 版本,带来的改进非常多:

类别特性
StringisBlanklinesstriprepeat
集合toArray(String[]::new)toList()
IOFiles.readStringFiles.writeString
HTTP标准 HTTP Client API
GCZGC 实验版、Epsilon GC
Lambda参数类型推断
运行时单文件源码执行
模块移除 Java EE/CORBA

JDK 11 是 JDK 8 之后最值得升级的版本——不仅有大量实用新 API,还有 ZGC 和 HTTP Client 这样的重磅功能。

基于 VitePress 构建