关于 JDK 11,首先要明确一点,他已经不新了——JDK 11 是2018年9月25日发布(General Availability)的。

部分新特性

下面是JDK11的部分新特性和新的API。

Local Var

在Lambda表达式中,可以使用var关键字来标识变量,变量类型由编译器自行推断。

  1. // LocalVar.java
  2. package com.itranswarp.jdk11;
  3. import java.util.Arrays;
  4. public class LocalVar {
  5. public static void main(String[] args) {
  6. Arrays.asList("Java", "Python", "Ruby")
  7. .forEach((var s) -> {
  8. System.out.println("Hello, " + s);
  9. });
  10. }
  11. }

HttpClient

长期以来,如果要访问Http资源,JDK的标准库中只有一个HttpURLConnection,这个古老的API使用非常麻烦,而且已经不适用于最新的HTTP协议。

JDK11的新的HttpClient支持HTTP/2和WebSocket,并且可以使用异步接口:

  1. // HttpApi.java
  2. package com.itranswarp.jdk11;
  3. import java.net.URI;
  4. import java.net.http.HttpClient;
  5. import java.net.http.HttpRequest;
  6. import java.net.http.HttpResponse;
  7. import java.util.concurrent.CompletableFuture;
  8. public class HttpApi {
  9. public static void main(String[] args) {
  10. HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://www.qq.com/")).GET().build();
  11. HttpResponse.BodyHandler<String> bodyHandler = HttpResponse.BodyHandlers.ofString();
  12. HttpClient client = HttpClient.newHttpClient();
  13. CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, bodyHandler);
  14. future.thenApply(HttpResponse::body).thenAccept(System.out::println).join();
  15. }
  16. }

List API

对于List接口,新增了一个of(T…)接口,用于快速创建List对象:

  1. List<String> list = List.of("Java", "Python", "Ruby");

List的toArray()还新增了一个重载方法,可以更方便地把List转换为数组。可以比较一下两种转换方法:

  1. // 旧的方法:传入String[]:
  2. String[] oldway = list.toArray(new String[list.size()]);
  3. // 新的方法:传入IntFunction:
  4. String[] newway = list.toArray(String[]::new);

读写文件
对Files类增加了writeString和readString两个静态方法,可以直接把String写入文件,或者把整个文件读出为一个String:

  1. Files.writeString(
  2. Path.of("./", "tmp.txt"), // 路径
  3. "hello, jdk11 files api", // 内容
  4. StandardCharsets.UTF_8); // 编码
  5. String s = Files.readString(
  6. Paths.get("./tmp.txt"), // 路径
  7. StandardCharsets.UTF_8); // 编码

这两个方法可以大大简化读取配置文件之类的问题。

String API

String新增了strip()方法,和trim()相比,strip()可以去掉Unicode空格,例如,中文空格:

  1. String s = " Hello, JDK11!\u3000\u3000";
  2. System.out.println(" original: [" + s + "]");
  3. System.out.println(" trim: [" + s.trim() + "]");
  4. System.out.println(" strip: [" + s.strip() + "]");
  5. System.out.println(" stripLeading: [" + s.stripLeading() + "]");
  6. System.out.println("stripTrailing: [" + s.stripTrailing() + "]");

输出如下:

  1. original: [ Hello, JDK11!  ]
  2. trim: [Hello, JDK11!  ]
  3. strip: [Hello, JDK11!]
  4. stripLeading: [Hello, JDK11!  ]
  5. stripTrailing: [ Hello, JDK11!]

新增isBlank()方法,可判断字符串是不是“空白”字符串:

  1. String s = " \u3000"; // 由一个空格和一个中文空格构成
  2. System.out.println(s.isEmpty()); // false
  3. System.out.println(s.isBlank()); // true

新增lines()方法,可以非常方便地按行分割字符串:

  1. String s = "Java\nPython\nRuby";
  2. s.lines().forEach(System.out::println);

新增repeat()方法,可以指定重复次数:

  1. System.out.println("-".repeat(10)); // 打印----------


除了新增的API外,JDK11还带来了EpsilonGC,就是什么也不做的GC,以及ZGC,一个几乎可以做到毫秒级暂停的GC。ZGC还处于实验阶段,所以启动它需要命令行参数-XX:+UnlockExperimentalVMOptions -XX:+UseZGC。

结论

JDK 11 是一个LTS版本(Long-Term-Support),我们在选择 Open JDK 11 用于后续开发。

关于 JDK 11 更详细的信息参见OPEN JDK 11 的官方信息: http://openjdk.java.net/projects/jdk/11/