Java 11 中的新功能
Java 11于 2018 年 9 月 25 日正式发布,这是一个长期支持 (LTS) 版本,请在此处下载 Java 11或此openJDK 存档。
Java 11 特性。
- 1. JEP 181:基于嵌套的访问控制
- 2. JEP 309:动态类文件常量
- 3. JEP 315:改进 Aarch64 内部函数
- 4. JEP 318:Epsilon:无操作垃圾收集器(实验性)
- 5. JEP 320:删除 Java EE 和 CORBA 模块
- 6. JEP 321:HTTP 客户端(标准)
- 7. JEP 323:Lambda 参数的局部变量语法
- 8. JEP 324:与 Curve25519 和 Curve448 的关键协议
- 9. JEP 327:Unicode 10
- 10. JEP 328:飞行记录器
- 11. JEP 329:ChaCha20 和 Poly1305 加密算法
- 12. JEP 330:启动单文件源代码程序
- 13. JEP 331:低开销堆分析
- 14. JEP 332:传输层安全 (TLS) 1.3
- 15. JEP 333:ZGC:可扩展的低延迟垃圾收集器(实验性)
- 16. JEP 335:弃用 Nashorn JavaScript 引擎
- 17. JEP 336:弃用 Pack200 工具和 API
Java 11 开发人员功能。
新的HTTP Client APIs java.net.http.*
,var
在lambda 参数中,Java 恐惧记录器(JFR),启动单文件程序java ClassName.java
,支持ChaCha20 密码算法。
最新 JDK 发布 Java 16
最新 Java 16 中的新功能。
1. JEP 181:基于嵌套的访问控制
它直接支持嵌套成员内的私有访问,不再通过自动生成的桥接方法access$000
。此外,新的嵌套 API 用于验证并允许嵌套成员内的私有反射访问。
在 Java 11 之前。
public class Alphabet {
private String name = "I'm Alphabet!";
public class A {
public void printName() {
System.out.println(name); // access Alphabet's private member!
}
}
}
如果我们编译上面的类,它会生成两个类,Alphabet
并且Alphabet$A
,即使是嵌套类也是具有唯一名称的典型类。JVM 访问规则不允许在不同的类中进行私有访问。但是,Java 允许嵌套成员内的私有访问,因此 Java 编译器创建了一个桥接方法access$000
来应用于 JVM 访问规则。
// After javac Alphabet.java, Java compiler created something similar to this.
public class Alphabet {
private String name = "I'm Alphabet!";
String access$000(){
return name;
}
}
public class Alphabet$A {
final Alphabet obj;
public void printName(){
System.out.println(obj.access$000());
}
}
在 Java 11 中,Java 编译器不会access$000
为嵌套成员内的私有访问生成任何桥接方法。这个新的 JVM 访问规则,基于 Nest 的访问控制,允许在 Nest 成员中进行私有访问。
进一步阅读
2. JEP 309:动态类文件常量
扩展类文件格式以支持新的常量池形式CONSTANT_Dynamic
、目标语言设计者和编译器实现者。
进一步阅读
3. JEP 315:改进 Aarch64 内部函数
优化了现有的字符串和数组内在函数Math.sin()
,Math.cos()
并Match.log()
在 Arm64 或Aarch64 处理器上实现了新的内在函数。这意味着更好的性能。
PS内在函数用于利用特定于 CPU 体系结构的汇编代码来提高性能。
进一步阅读
4. JEP 318:Epsilon:无操作垃圾收集器(实验性)
一个新的 No-Op(无操作)垃圾收集器,它分配内存但不会收集任何垃圾(内存分配),一旦 Java 堆耗尽,JVM 将关闭。
几个用例:
- 性能测试
- 虚拟机接口测试
- 短期工作
此 GC 是一个实验性功能;我们需要使用以下选项来启用新的 Epsilon GC。
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
进一步阅读
5. JEP 320:删除 Java EE 和 CORBA 模块
Java 9 弃用了以下 Java EE 和 CORBA 模块,现在已在 Java 11 中删除。如果您想迁移到 Java 11,请确保您的项目未使用以下任何包或工具。
删除的包:
- java.xml.ws (JAX-WS)
- java.xml.bind (JAXB)
- java.activation (JAF)
- java.xml.ws.annotation(通用注解)
- java.corba (CORBA)
- java.transaction(JTA)
- java.se.ee(上述六个模块的聚合器模块)
删除的工具:
- wsgen 和 wsimport(来自 jdk.xml.ws)
- schemagen 和 xjc(来自 jdk.xml.bind)
- idlj、orbd、servertool 和 tnamesrv(来自 java.corba)
进一步阅读
6. JEP 321:HTTP 客户端(标准)
这HTTP Client API
,在java.net.http
包是在Java的9中引入,在Java 11更新Java的10,现在的标准功能。
一个 Java 11HttpClient
发送一个简单的GET
请求。
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("https://httpbin.org/get"))
.setHeader("User-Agent", "Java 11 HttpClient Bot")
.build();
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
HttpHeaders headers = response.headers();
headers.map().forEach((k, v) -> System.out.println(k + ":" + v));
System.out.println(response.statusCode());
System.out.println(response.body());
进一步阅读
7. JEP 323:Lambda 参数的局部变量语法
此 JEP 添加了对var
lambda 参数中的关键字的支持。
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream()
.map((var x) -> x.toUpperCase())
.collect(Collectors.joining(","));
System.out.println(result2);
但是,lambda 可以进行类型推断;上面的例子相当于:
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream()
.map(x -> x.toUpperCase())
.collect(Collectors.joining(","));
那么,为什么这个 JEP 添加var
了 lambda 参数?好处是现在我们可以为 lambda 参数添加注释,请参见此示例:
import org.jetbrains.annotations.NotNull;
List<String> list = Arrays.asList("a", "b", "c", null);
String result = list.stream()
.map((@NotNull var x) -> x.toUpperCase())
.collect(Collectors.joining(","));
System.out.println(result3);
进一步阅读
8. JEP 324:与 Curve25519 和 Curve448 的关键协议
Java 密码学相关项目。它用Curve25519和Curve448算法取代了现有的椭圆曲线 Diffie-Hellman (ECDH) 方案,这是RFC 7748 中定义的密钥协议方案。
KeyPairGenerator
使用该Curve25519
算法生成密钥对的简单示例。
package com.mkyong.java11.jep324;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.NamedParameterSpec;
public class GenerateKeyPairs {
public static void main(String[] args) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
kpg.initialize(paramSpec); // equivalent to kpg.initialize(255)
// alternatively: kpg = KeyPairGenerator.getInstance("X25519")
KeyPair kp = kpg.generateKeyPair();
System.out.println("--- Public Key ---");
PublicKey publicKey = kp.getPublic();
System.out.println(publicKey.getAlgorithm()); // XDH
System.out.println(publicKey.getFormat()); // X.509
// save this public key
byte[] pubKey = publicKey.getEncoded();
System.out.println("---");
System.out.println("--- Private Key ---");
PrivateKey privateKey = kp.getPrivate();
System.out.println(privateKey.getAlgorithm()); // XDH
System.out.println(privateKey.getFormat()); // PKCS#8
// save this private key
byte[] priKey = privateKey.getEncoded();
}
}
进一步阅读
9. JEP 327:Unicode 10
这意味着更多的代码点,更多的表情符号 🙂 下面的例子打印了一个 Unicode 代码点。
package com.mkyong.java11;
public class PrintUnicode {
public static void main(String[] args) {
String codepoint = "U+1F92A"; // crazy face
System.out.println(convertCodePoints(codepoint));
}
// Java, UTF-16
// Convert code point to unicode
static char[] convertCodePoints(String codePoint) {
Integer i = Integer.valueOf(codePoint.substring(2), 16);
char[] chars = Character.toChars(i);
return chars;
}
}
进一步阅读
10. JEP 328:飞行记录器
Java Flight Recorder (JFR) 是 Oracle JDK 中的一个商业产品,现在它在 OpenJDK 11 中开源。这个 JFR 是一个分析工具,用于诊断正在运行的 Java 应用程序。以下命令在 Java 应用程序上启动 60 秒 JFR 记录,将记录的数据转储到“.jfr”文件中。
$ java -XX:StartFlightRecording=duration=60s,settings=profile,filename=app.jfr MyHelloWorldApp
那么如何处理.jfr
文件呢?我们可以使用Java Mission Control (JMC)来分析和可视化.jfr
文件。
进一步阅读
11. JEP 329:ChaCha20 和 Poly1305 加密算法
ChaCha20
是一种高速流密码,一种加解密算法。ChaCha20-Poly1305
表示ChaCha20
在 AEAD 模式下与Poly1305
身份验证器、加密和身份验证一起运行,两者都在RFC 7539中定义。这个ChaCha20
加密算法的JEP 更新是对不安全的RC4流密码的替代。
的输入ChaCha20
是:
- 一个 256 位的密钥(32 字节)
- 96 位随机数(12 字节)
- 32 位初始计数(4 字节)
Cipher cipher = Cipher.getInstance("ChaCha20");
ChaCha20ParameterSpec param = new ChaCha20ParameterSpec(nonce, counter);
cipher.init(Cipher.ENCRYPT_MODE, key, param);
byte[] encryptedText = cipher.doFinal(pText);
请参考这个Java 11 – ChaCha20 Stream Cipher 示例
的输入ChaCha20-Poly1305
是:
- 一个 256 位的密钥(32 字节)
- 96 位随机数(12 字节)
Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305");
// IV, initialization value with nonce
IvParameterSpec iv = new IvParameterSpec(nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encryptedText = cipher.doFinal(pText);
进一步阅读
12. JEP 330:启动单文件源代码程序
这个单文件源代码程序是指在一个源代码.java
文件中的整个 Java 程序。这个JEP是早期学习Java的一个友好特性,但是对Java开发没有太大的好处,大家都用IDE。
查看单个文件源代码。
public class HelloJava {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
在 Java 11 之前。
$ javac HelloJava.java
$ java HelloJava
Hello World!
现在是 Java 11。
$ java HelloJava.java
Hello World!
舍邦#!
现在,单个 Java 程序可以使用 Linux Shebang 作为脚本运行。
#!/opt/java/openjdk/bin/java --source 11
public class SheBang {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
进一步阅读
13. JEP 331:低开销堆分析
Java 虚拟机工具接口 (JVMTI) 是在 J2SE 5、JDK 5 (Tiger) 中引入的,它提供了用于分析或监视工具以访问 JVM 状态的 API。这个 JEP 在 JVMIT 中添加了新的低开销堆分析 API。
进一步阅读
14. JEP 332:传输层安全 (TLS) 1.3
Java 11 支持RFC 8446传输层安全 (TLS) 1.3 协议。但是,并非所有 TLS 1.3 功能都已实现,请参阅此JEP 332了解详细信息。
Java 安全套接字扩展 (JSSE) + TLS 1.3 示例。
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
SSLSocketFactory factory =
(SSLSocketFactory) SSLSocketFactory.getDefault();
socket =
(SSLSocket) factory.createSocket("google.com", 443);
socket.setEnabledProtocols(new String[]{"TLSv1.3"});
socket.setEnabledCipherSuites(new String[]{"TLS_AES_128_GCM_SHA256"});
进一步阅读
15. JEP 333:ZGC:可扩展的低延迟垃圾收集器(实验性)
Z Garbage Collector (ZGC) 是一个实验性的垃圾收集器;它具有不超过 10 毫秒的低暂停时间。此 ZCG 仅在 Linux/64 上支持。
- 在 Java 14 中,此 ZCG 扩展了对 macOS JEP 364和 Windows JEP 365 的支持。
- 这个 ZGC 垃圾收集器是 Java 15 JEP 377 中的一个产品特性。
进一步阅读
16. JEP 335:弃用 Nashorn JavaScript 引擎
Nashorn JavaScript 脚本引擎和jjs
工具已弃用,并且可能会在未来版本中删除。
历史
- Java 8 JEP 174引入了 Nashorn,作为 Rhino Javascript 引擎的替代品。
- Java 11 JEP 335弃用了 Nashorn。
- Java 15 JEP 372删除了 Nashorn JavaScript 引擎和 jjs 工具。
进一步阅读
17. JEP 336:弃用 Pack200 工具和 API
这JEP弃用了pack200
和unpack200
工具,以及Pack200
在APIjava.util.jar
包,它会在将来的版本中可能删除。
PS Java 14 JEP 367删除了 Pack200 工具和 API。
进一步阅读
下载源代码
$ git clone https://github.com/mkyong/core-java
$ cd java-11
参考
- OpenJDK 11 项目
- Java版本历史
- Unicode 10
- 维基百科——Aarch64 处理器
- 维基百科 – 内在
- Java 安全性有哪些新变化?
- Oracle – Java 安全标准算法名称
- RFC 7748
- 维基百科 – Curve25519
- 维基百科 – Curve448
- Java 飞行记录器
- Java 任务控制 (JMC)
- RFC 7539
- Java 11 - 芯片
- ChaCha20
- RC4
- Java 11 – ChaCha20 流密码示例
- Java 11 – ChaCha20-Poly1305 加密示例
- Docker 中的 Java 11 shebang 示例
- 维基百科——Java 虚拟机工具接口
- Oracle – JVMTM 工具接口
- Java SSLSocket TLS 1.3 示例
- RFC 8446
- Oracle – Java 安全开发人员指南
- 甲骨文——Z 垃圾收集器
- OpenJDK Wiki – ZCG
- 甲骨文——Z 垃圾收集器
- Java 11 HttpClient 示例