Open JDK 11 新特性解读

Open JDK 11 新特性解读

JDK11是继JDK8后的第一个LTS(Long Time Support)版本。


安装

《如何在IDEA中切换多版本JDK》


重要JEP

JEP(JDK Enhancement Proposals)是JDK增强体验的简称,是Java社区给出的JDK优化建议。

JEP-JDK11

首先你可以看看《如何在IDEA中切换多版本JDK》,源代码放在了https://github.com/DragonBaby308/JEP11-12

JEP181:基于嵌套的访问控制

在用户看来,所有嵌套类都是属于同一个类的,当然希望所有内部类共享同样的访问控制机制,所以往往会将嵌套类中的属性修饰为package或是public,但是这不符合面向对象的封装理念。

privateprotectedpublic的基础上,JVM提供了一种新的访问控制机制:Nest
如果你在一个类中嵌套了多个内部类,那么内部类相互可以访问彼此的private资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class JEP181_NestDemo {

public static class A{
private int num;
}

public static class B{
public void opsNum() throws Exception{
A a = new A();
a.num = 1;
//反射获取变量
Field field = A.class.getDeclaredField("num");
// 在嵌套类B中操作嵌套类A中的private成员
// Java8不加field.setAccess(true)是无法编译通过的,抛出java.lang.IllegalAccessException
// Java11则可以直接编译通过
// field.setAccessible(true);
field.setInt(a, 2);
}
}

public static void main(String[] args) throws Exception{
new B().opsNum();
}
}

JEP309:动态类文件常量

Class文件中新增一个常量类型CONSTANT_Dynamic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class JEP309_DynamicDemo {

public static void test() {
System.out.println("xxxxxxxxxxx");
}

public static void main(String[] args) throws Throwable{
//通过MethodHandle动态调用
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle ml = lookup.findStatic(
JEP309_DynamicDemo.class, "test", MethodType.methodType(void.class)
);
ml.invokeExact();
}

}

JEP321:标准HTTP Client

将标准的HTTP Client作为API放到java.net.http包下,用于替代HttpURLConnection,提供同步连接 / 异步连接服务。

  1. 创建客户端:HttpClient httpClient = HttpClient.newHttpClient();
  2. 创建请求: HttpRequest request = HttpRequest.newBuilder.uri(URI.create(uri)).build();
  3. 同步get: HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString() );
  4. 异步get:CompletableFuture<HttpResponse<String>> response = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString() );

    获取异步查询结果:future.whenComplete(…).join();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package jdk11;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

/**
* @program: jep_11_12_demo
* @description: HTTP Client API,实现了HTTP/2
* @author: DragonBaby308
* @create: 2019-07-28 10:02
* @version: 1.0
**/
public class JEP321_HTTPClient {

//同步连接
public static void syncGet(String uri) throws Exception {
//静态工厂方法创建客户端
HttpClient httpClient = HttpClient.newHttpClient();
//构造器模式:构造请求
HttpRequest request = HttpRequest.newBuilder().uri(
URI.create(uri)
).build();
HttpResponse<String> response = httpClient.send(
request,
HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.statusCode()); //状态码
System.out.println(response.body()); //数据
}

//异步连接
public static void asyncGet(String uri) throws Exception {
//静态工厂方法创建客户端
HttpClient httpClient = HttpClient.newHttpClient();
//构造器模式:构造请求
HttpRequest request = HttpRequest.newBuilder().uri(
URI.create(uri)
).build();
//CompleteFuture获取异步结果
CompletableFuture<HttpResponse<String>> future =
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());
//阻塞异步结果
future.whenComplete( (resp, ex) -> {
if(ex != null) {
ex.printStackTrace();
}else {
System.out.println(resp.statusCode());
System.out.println(resp.body());
}
}).join();
}

public static void main(String[] args) throws Exception{
String uri = "http://t.weather.sojson.com/api/weather/city/101030100";
syncGet(uri);
asyncGet(uri);
}
}

JEP323:本地变量Lambda语法

允许在Lambda表达式中声明隐式类型参数时,使用var局部类型推断,主要是方便使用注解,但是要注意,不允许显示类型和隐式类型混用,即(int x, var y) ->是不允许的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class JEP323_LambdaDemo {

public static void sortWithLambdaAndVar() {
List<Integer> list = Arrays.asList(8,9,7);
//排序
list.sort((Integer s1, Integer s2) -> {
if (s1.equals(s2)) {
return 0;
}else{
return s1 > s2 ? 1 : -1;
}
});
System.out.println(list);

list = Arrays.asList(8,9,7);
//JDK11之前不允许在Lambda表达式中使用var
list.sort((@NotNull var s1, @NotNull var s2) -> {
if (s1.equals(s2)) {
return 0;
}else{
return s1 > s2 ? 1 : -1;
}
});
System.out.println(list);
}

public static void main(String[] args) {
// var i; //var变量必须初始化,否则编译不通过
var i = 10;
// i = "a"; //var变量有原始值,不能改变
sortWithLambdaAndVar();
}
}

JEP327:Unicode10

java.lang.Characterjava.lang.Stringjava.awt.font.NumericShaperjava.text.Bidi……支持Unicode10

如:System.out.println("\uD83E\uDDDA");
Unicode10

JEP333:可伸缩低延迟垃圾收集器(ZGC)

无论开辟了多大的堆内存,都可以保证低于10ms的JVM停顿,也就是说JVM停顿与堆内存无关,远胜于前一代的G1。
详见《深入理解JVM》


新增API

String

.strip()

.strip()可以去除Unicode空格\u3000,比如中文空格。

源码:

1
2
3
4
public String strip() {
String ret = isLatin1() ? StringLatin1.strip(value) : StringUTF16.strip(value);
return ret == null ? this : ret;
}

.isBlank()

.isBlank()可以检测Unicode空格\u3000

源码:

1
2
3
4
5
6
7
8
9
10
11
public boolean isBlank() {
return indexOfNonWhitespace() == length();
}

private int indexOfNonWhitespace() {
if (isLatin1()) {
return StringLatin1.indexOfNonWhitespace(value);
}else{
return StringUTF16.indexOfNonWhitespace(value);
}
}

.lines()

.lines()可以检测\n换行符,将字符串分割成不同的流。

源码:

1
2
3
public Strem<String> lines() {
return isLatin1() ? StringLatin1.lines(value) : StringUTF16.lines(value);
}

.repeat(int n)

重复字符串n次。

.stripLeading()

去除所有前导Unicode空格\u3000,比如中文空格。

.stripTrailing()

去除所有尾随Unicode空格\u3000,比如中文空格。

File:readString() & writeString()

可以方便地读写字符串到文件,简化配置文件读取和写入

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class StringAndFileNewAPI {
public static void main(String[] args) throws Exception{
String s = "\u3000Hello,JDK11\u3000";
String empty = "\u3000";
//对比trim() & strip()
System.out.println("原字符串:"+s);
System.out.println("调用.trim()后:"+s.trim());
System.out.println("调用.strip()后:"+s.strip());
System.out.println("调用.stripLeading()后:"+s.stripLeading());
System.out.println("调用.stripTrailing()后:"+s.stripTrailing());
//对比isEmpty() & isBlank()
System.out.println("isEmpty():"+empty.isEmpty());
System.out.println("isBlank():"+empty.isBlank());
//lines()
String lines = "Hello\nJDK\n11";
lines.lines().forEach(System.out::println);
//repeart()
System.out.println("repeat(3):"+ s.repeat(3));

//========================================================

System.out.println("=========================File========================");
String path = "/temp/jdk11.txt";
Files.writeString(Path.of(path),
"jdk11_new_feature", StandardCharsets.UTF_8);
System.out.println(Files.readString(Paths.get(path), StandardCharsets.UTF_8));
}
}
-------------本文结束感谢您的阅读-------------

本文标题:Open JDK 11 新特性解读

文章作者:DragonBaby308

发布时间:2019年07月24日 - 08:23

最后更新:2019年09月22日 - 10:13

原始链接:http://www.dragonbaby308.com/jdk11/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%