概述
2018 年 9 月 26 日,Oracle 官方发布 Java 11。这是 Java 大版本周期变化后的第一个长期支持版本,非常值得关注。最新发布的 Java 11 将带来 ZGC、HttpClient 等重要特性,一共 17 个需要我们关注的 JEP。
参考文档:openjdk.java.net/projects/jd…
语法层次变化
局部变量类型推断升级
局部变量类型推断是 Java 10 开始新增的新特性,Java 11 中对局部变量推断进行了升级。在 var
支持添加注解的语法格式,Java 10 中是无法实现的,在 Java 11 中加入了这样的语法:
Lambda 表达式中,注解修饰变量的时候,变量的数据类型必须要写,不能省略。像下面这种写法就是错误的:
Consumer<String> con =(@Deprecated t) -> System.out.println(t.toLowerCase());
这个时候就必须要为小括号中的参数添加数据类型,应该这样写:
Consumer<String> con = (@Deprecated String t) -> System.out.println(t.toLowerCase());
Java 11 中,Lambda 表达式中的参数数据类型可以使用 var,但是不能不写:
Consumer<String> con = (@Deprecated var t) -> System.out.println(t.toLowerCase());
API层次变化
新的String API
在 Java 11 中对 String
处理新增的很多方法。简化对字符串的操作:
描述 | 举例 |
---|---|
判断字符串是否为空白 | " ".isBlank(); // true |
去除字符串首尾空白 | " ".strip(); // "www.boge.com" |
去除字符串尾部空格 | " www.baidu.com ".stripTrailin(); // " www.baidu.com" |
去除字符串首部空格 | " www.baidu.com ".stripLeading(); // "www.baidu.com " |
复制字符串 | "foo".repeat(2); // "foofoo" |
行数统计 | "A\nB\nC\nD".lines().count(); // 4 |
Optional新的API
Optional
也增加了几个非常好用的方法,现在可以很方便的把一个 Optional
转换成一个 Stream
,或者当一个空 Optional
时,给它一个替代的值。我们发现从 Java 8 开始出现 Stream 以后,每个版本都有相关的更新。
新增方法 | 描述 | 新增版本 |
---|---|---|
boolean isEmpty() | 判断 value 是否为空 | JDK11 |
public static void main(String[] args) {
Optional<String> optional = Optional.empty();
// JDK11 判断value是否为空
// true
System.out.println(optional.isEmpty());
}
HttpClient
Java 9 开始引入一个处理 HTTP 请求的 HttpClient API,该 API 支持同步和异步。可以使用 Java 9 引入的 Java 模块系统引入 HttpClient 模块。而在 Java 11 中成为正式可用状态,可以在 java.net 包中找到这个 API,它将替代仅适用于 blocking
模式的 HTTPUrlConnection
(创建于 Http1.0 时代,并使用了协议无关的方法),并提供对 WebSocket 和 Http2 的支持。
// HttpClient 替换原有的 HttpUrlConnection 同步方式
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/demo")).build();
HttpResponse.BodyHandler<String> respnoseBodyHandler = HttpResponse.BodyHandlers.ofString();
HttpResponse<String> response = client.send(request, respnoseBodyHandler);
String body = response.body();
System.out.println(body);
// HttpClient 替换原有的 HttpUrlConnection 异步方式
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/demo")).build();
HttpResponse.BodyHandler<String> respnoseBodyHandler = HttpResponse.BodyHandlers.ofString();
CompletableFuture<HttpResponse<String>> sendAsync = client.sendAsync(request, respnoseBodyHandler);
sendAsync.thenApply(t -> t.body()).thenAccept(System.out::println);
其他变化
更简单的编译与运行
Java 11 提供了更简化的编译运行程序,编译并运行一个 Java 源代码文件语法应该是:
javac Test.java
java Test
而在 Java 11 中,通过一个 Java 命令就可以直接搞定了,语法是:
java Test.java
需要注意的是:
源代码文件中如果有多个类,执行源文件中的第一个类中主方法。注意这里的第一个是代码顺序的第一个,和是否由public
修饰无关。
不可以使用其他源文件中定中自定义的类,当前文件中自定义的类是可以使用的。
ZGC
GC 是 Java 的主要优势之一(另一个是强大的 JVM),永远都是 Java 优化的一个核心点。然而,当 GC 的 STW(stop the world)太长,就会影响应用的响应时间。消除或者减少 GC 的停顿时长,将会使 Java 对更广泛的引用场景成为一个更具有吸引力的平台。此外,现代系统中可用内存不断增长,用户和程序员希望 JVM 能够以更高效的方式利用这些内存,并且无需长时间 STW。
ZGC:A Scalable Low-Latency Garbage Collector(Experimental)。作为 Java 11 最瞩目的特征,但是后面带了 Experimental,说明是实验版本,,就不建议在生产环境中使用。ZGC 是一个并发,基于 region 的压缩性垃圾收集器,只有 root 扫描阶段会 STW,因此 GC 停顿时间不会随着堆的增长和存活对象的增长而变长。
优势:
- 暂停时间不会超过 10 ms。
- 既能处理几百兆的小堆,也能处理几个 T 的大堆(OMG)。
- 和 G1 相比,应用吞吐能力不会下降超过 15%。
- 为未来的 GC 功能和利用 colored 指针以及 Load Barriers 优化奠定基础。
- 初始只支持 64 位系统。
设计目标:
- 支持 TB 级内存容量,暂停时间低(<10ms),对整个程序吞吐量的影响小于 15%。
- 将来还可以扩展实现机制,用以支持很多让人兴奋的功能,如多层堆或者压缩堆。
多层堆即对象置于 DRAM 和冷对象置于 NVMe 闪存。
了解内容
- Unicode 10。
- Deprecate The Pack200 Tools and API。
- 新的 Epsilon 垃圾收集器。
- 完全支持 Linux 容器,包括 Docker。
- 支持 G1 上的并行完全垃圾收集。
- 最新的 HTTPS 安全协议 TLS 1.3。
- JAVA Flight Recoder。