更多 Java 高级知识方面的文章,请参见文集《Java 高级知识》
JDK 11 reached General Availability on 25 September 2018. Production-ready binaries under the GPL are available from Oracle; binaries from other vendors will follow shortly.
JDK 11 的新特性包括:做一个简单分类
工具 Tooling 相关:
318: Epsilon: A No-Op Garbage Collector
这是一个垃圾回收器,但是它实际上不做任何的垃圾回收。如果堆内存满了,虚拟机直接退出。
那有啥用?可以用于性能测试和堆内存的压力测试。
330: Launch Single-File Source-Code Programs
直接通过 java HelloWorld.java 执行 Java 源代码,不需要手动来编译。
Under The Hood Stuff:引擎盖下的东西,意思是不会实际影响到你的使用
181: Nest-Based Access Control
如果你在一个类中嵌套了多个子类,那么子类中可以访问彼此的私有成员。
315: Improve Aarch64 Intrinsics
会提升字符串,数组的操作性能,也会提高标准数学运算的性能,例如 Math.sin Math.cos。
320: Remove the Java EE and CORBA Modules
它们在 Java 9 中被标记为过时,在 Java 11 中彻底移除。
本文将结合一些具体的代码示例,介绍Java 11 新特性(更新中)。
JDK 11 在 Mac 上的下载及安装
安装完成后,可以看到本机存在了两个版本的 SDK:
本机存在了两个版本的 SDK
如果是通过 IntelliJ IDEA 来开发 Java,需要切换 JDK 的版本和源代码的 Language Level:
IntelliJ IDEA 切换 JDK 的版本
IntelliJ IDEA 切换源代码的 Language Level
一些示例
323: Local-Variable Syntax for Lambda Parameters
从 JDK 10开始,引入了 var 类型推断,例如:
var s = "Hello JDK10";
System.out.println(s);
但是它有几个限制:
只能用于局部变量上
声明时必须初始化
不能用作方法参数
不能在 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)
在 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 response =
client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
327: Unicode 10
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 ss = s4.lines();
ss.forEach(s -> System.out.println(s));
System.out.println("A".repeat(3)); //AAA
330: Launch Single-File Source-Code Programs
之前你可以用 java 命令来运行一个 Java 二进制文件文件,例如 java HelloWorld.class
现在你可以用 java 命令来直接运行一个 Java 源代码文件,例如 java HelloWorld.java,例如:
此命令相当于:
javac -d HelloWorld.java
java -cp 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
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))); // 打印2
更新中