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.jarHTTP 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 版本,带来的改进非常多:
| 类别 | 特性 |
|---|---|
| String | isBlank、lines、strip、repeat |
| 集合 | toArray(String[]::new)、toList() |
| IO | Files.readString、Files.writeString |
| HTTP | 标准 HTTP Client API |
| GC | ZGC 实验版、Epsilon GC |
| Lambda | 参数类型推断 |
| 运行时 | 单文件源码执行 |
| 模块 | 移除 Java EE/CORBA |
JDK 11 是 JDK 8 之后最值得升级的版本——不仅有大量实用新 API,还有 ZGC 和 HTTP Client 这样的重磅功能。
