Java11新特性简介
美国时间 2018年09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本。
可以看出 Java 8 扩展支持到 2025 年,而 Java 11 扩展支持到 2026 年。
现在大部分都在用 Java 8,Java 9 和 10 目前很少有人在用,现在 Java 11 长期支持,也已经包含了 9 和 10 的全部功能,9 和 10 自然就活到头了。。
预测:
Java12添加自动属性 get; set;
Java13添加线程包装类Task
Java14添加异步语法async await
Java15添加协程
Java16添加let
。。。
参考:https://www.jianshu.com/p/a3f95b8214f2
JDK 11 的新特性包括:做一个简单分类
- 语言和 API 的更新:
323: Local-Variable Syntax for Lambda Parameters
321: HTTP Client (Standard)
327: Unicode 10
- 安全 Security 相关:
324: Key Agreement with Curve25519 and Curve448–使用 Java 实现了 Key Agreement,之前是 C 实现的。
329: ChaCha20 and Poly1305 Cryptographic Algorithms–新的加密方式,广泛应用于 TLS。
332: Transport Layer Security (TLS) 1.3–TLS 1.3 在安全性和性能方面做了很多提升。
- 工具 Tooling 相关:
318: Epsilon: A No-Op Garbage Collector–这是一个垃圾回收器,但是它实际上不做任何的垃圾回收。如果堆内存满了,虚拟机直接退出。
那有啥用?可以用于性能测试和堆内存的压力测试。
328: Flight Recorder
330: Launch Single-File Source-Code Programs–直接通过 java HelloWorld.java 执行 Java 源代码,不需要手动来编译。
331: Low-Overhead Heap Profiling–用来做内存分析的工具。
333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)–这是一个垃圾回收器,可以大大减少回收垃圾时系统的停顿时间。目前仅支持 Linux/x64 平台。 - Under The Hood Stuff:引擎盖下的东西,意思是不会实际影响到你的使用
181: Nest-Based Access Control–如果你在一个类中嵌套了多个子类,那么子类中可以访问彼此的私有成员。
309: Dynamic Class-File Constants–扩展了字节码文件的格式,用来支持新的常量池。
315: Improve Aarch64 Intrinsics–会提升字符串,数组的操作性能,也会提高标准数学运算的性能,例如 Math.sin Math.cos。
320: Remove the Java EE and CORBA Modules–它们在 Java 9 中被标记为过时,在 Java 11 中彻底移除。 - 移除过时的东西:
335: Deprecate the Nashorn JavaScript Engine–为啥?因为实在是跟不上 ECMAScript 更新的节奏啊。
336: Deprecate the Pack200 Tools and API–为啥?因为 Java 9 引入了新的压缩打包方式。
- 以下为用例Demo
- 323: Local-Variable Syntax for Lambda Parameters
参考:http://openjdk.java.net/jeps/323
从 JDK 10开始,引入了 var 类型推断,例如:
var s = "Hello JDK10";
System.out.println(s);
但是它有几个限制:
1、只能用于局部变量上
2、声明时必须初始化
3、不能用作方法参数
4、不能在 Lambda 表达式中使用
JDK 11 则允许在 Lambda 表达式中使用 var,例如:
var numbers = new int[]{1, 2, 3, 4, 5, 6, 7};
int[] subset = Arrays.stream(numbers).filter((var a) -> a > 5).toArray();
for (int i = 0; i < subset.length; i++) {
System.out.println(subset[i]);
}
- 321: HTTP Client (Standard)
参考:http://openjdk.java.net/jeps/321
在 JDK 9 中就已经引入了 HTTP Client,不过一直处于孵化状态,到了 JDK 11,HTTP Client API 结束了孵化状态,作为一个标准 API 提供在 java.net.http 包中。
java.net.http 包参见:https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/package-summary.html
一个示例:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.baidu.com/"))
.build();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
- 327: Unicode 10
参考:http://openjdk.java.net/jeps/327
关于 Unicode 10 的标准,参见 http://unicode.org/versions/Unicode10.0.0/。
Unicode 10.0 adds 8,518 characters, for a total of 136,690 characters. These additions include 4 new scripts, for a total of 139 scripts, as well as 56 new emoji characters.
因此 JDK 11 更新了已有的 API 来支持最新的 Unicode 10 标准,主要体现在如下的类:
java.lang 包中的 Character, String
java.awt.font 包中的 NumericShaper
java.text包中的 Bidi, BreakIterator, Normalizer
例如:
String emoj = "\ud83d\ude02\ud83d\ude0d\ud83c\udf89\ud83d\udc4d";
System.out.println(emoj); // ????
String 类中新的 API
JDK 11 中新增的 String API 包括:
public String strip() 去除前后的空格
public String stripLeading() 去除前面的空格
public String stripTrailing() 去除后面的空格
public boolean isBlank() 判断是否为空,或者只含有空格
public Stream lines() 依据 line terminators (\n \r \r\n) 来进行分割
public String repeat(int count) 将字符串重复n次
例如:
String s1 = " Testing ";
System.out.println(s1.strip()); //Testing
String s2 = " Testing ";
System.out.println(s1.stripLeading()); //Testing空格
String s3 = " Testing ";
System.out.println(s1.stripTrailing()); //空格Testing
System.out.println(" ".isBlank()); //true
String s4 = "A\nB\nC";
Stream<String> ss = s4.lines();
ss.forEach(s -> System.out.println(s));
System.out.println("A".repeat(3)); //AAA
- 330: Launch Single-File Source-Code Programs
参考:http://openjdk.java.net/jeps/330
之前你可以用 java 命令来运行一个 Java 二进制文件文件,例如 java HelloWorld.class
现在你可以用 java 命令来直接运行一个 Java 源代码文件,例如 java HelloWorld.java,例如:
此命令相当于:
javac -d <memory> HelloWorld.java
java -cp <memory> HelloWorld
提供这个功能并不是为了改变 Java 的语言特性,也不是为了将它变为一个脚本语言。只是为了简化 Single-File Source-Code 单文件的执行流程。
- 328: Flight Recorder(JFR)
参考:http://openjdk.java.net/jeps/328
Provide a low-overhead data collection framework for troubleshooting Java applications and the HotSpot JVM. 提供了一个低开销的数据收集框架,用来分析 Java 程序和 HotSpot 虚拟机。
Provide APIs for producing and consuming data as events 提供了 API 来生产和消费事件 Events
Provide a buffer mechanism and a binary data format 提供了缓冲机制和二进制数据格式
Allow the configuration and filtering of events 允许事件的配置和过滤
Provide events for the OS, the HotSpot JVM, and the JDK libraries 提供了针对操作系统,虚拟机和 JDK 类库的事件
我们可以通过如下的代码来生产一个 event:
package jdk11;
import jdk.jfr.Description;
import jdk.jfr.Event;
import jdk.jfr.Label;
import java.io.IOException;
@Label("Hello World")
@Description("Helps the programmer getting started")
class HelloWorld extends Event {
@Label("Message")
String message;
public static void main(String... args) throws IOException {
HelloWorld event = new HelloWorld();
event.message = "hello, world!";
event.commit();
}
}
随后通过 java -XX:StartFlightRecording=duration=60s,name=Test,filename=recording.jfr,settings=profile jdk11/HelloWorld 来执行,会产生一个文件 recording.jfr。
随后我们可以通过如下代码来消费这个 event:
package jdk11;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingFile;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class EventConsumer {
public static void main(String... args) throws IOException {
Path p = Paths.get("recording.jfr");
for (RecordedEvent e : RecordingFile.readAllEvents(p)) {
System.out.println(e.getStartTime() + " : " + e.getValue("message"));
}
}
}
- 331: Low-Overhead Heap Profiling
参考:http://openjdk.java.net/jeps/331
Provide a low-overhead way of sampling Java heap allocations, accessible via JVMTI. 提供了一个低开销的方式来对 Java 堆内存的分配进行采样。
一些新的 API
TimeUnit
TimeUnit tu = TimeUnit.DAYS;
// 将 50 小时转换为天数
System.out.println(tu.convert(Duration.ofHours(50)))