自Java11起,Oracle JDK将不再免费提供商业用途。
Java11是Java8后的第一个LTS版本,我们对OpenJDK的特性列表做一些分析。
简介
以下是Java11的特性清单:
- 181: Nest-Based Access Control(基于嵌套的访问控制)
- 309: Dynamic Class-File Constants(动态的类文件常量)
- 315: Improve Aarch64 Intrinsics(优化Aarch64内在函数)
- 318: Epsilon: A No-Op Garbage Collector(一个无操作垃圾收集器)
- 320: Remove the Java EE and CORBA Modules(移除Java EE和CORBA模块)
- 321: HTTP Client (Standard) (HTTP Client API)
- 323: Local-Variable Syntax for Lambda Parameters (lambda参数的局部变量语法)
- 324: Key Agreement with Curve25519 and Curve448
- 327: Unicode 10 (对unicode10的支持)
- 328: Flight Recorder(飞行记录器)
- 329: ChaCha20 and Poly1305 Cryptographic Algorithms
- 330: Launch Single-File Source-Code Programs (运行单文件程序)
- 331: Low-Overhead Heap Profiling
- 332: Transport Layer Security (TLS) 1.3
- 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
- 335: Deprecate the Nashorn JavaScript Engine (弃用Nashron)
- 336: Deprecate the Pack200 Tools and API
提出问题:
- 那些是日常会用到的?重点是?
代码及完整文件地址:
https://github.com/teaho2015-blog/java11-feature-learning
181: Nest-Based Access Control(基于嵌套的访问控制)
我们先看一个例子:
public class JEP181 {
public static class Nest1 {
private int varNest1;
public void f() throws Exception {
final Nest2 nest2 = new Nest2();
//这里没问题
nest2.varNest2 = 2;
final Field f2 = Nest2.class.getDeclaredField("varNest2");
//这里在java8环境下会报错,在java11中是没问题的
f2.setInt(nest2, 2);
System.out.println(nest2.varNest2);
}
}
public static class Nest2 {
private int varNest2;
}
public static void main(String[] args) throws Exception {
new Nest1().f();
}
}
该改动要解决的问题:
-
Java语言规范允许在同一个源文件中编写多个类。对于用户的角度来说,在同一个类文件里的class应该共享同样的访问控制体系。 为了达到目的,编译器需要经常需要通过附加的access bridge扩大private成员的访问权限到package。 这种bridge和封装相违背,并且轻微的增加程序的大小,会干扰用户和工具。
-
还有一个问题是反射与源码调用不一致。当使用java.lang.reflect.Method.invoke从一个nestmate调用另一个nestmate私有方法时会报IllegalAccessError错误。 这个是让人不能理解的,因为反射应该和源码级访问拥有相同权限。
现有情况:
现有的类文件格式定义了 InnerClasses 和 EnclosureMethod 属性(JVMS 4.7.6 和 4.7.7),以允许 Java 源代码编译器(如 javac)具体化源级嵌套关系。
每个嵌套类型都编译为它自己的类文件,不同的类文件通过这些属性的值“链接”。
虽然这些属性足以让 JVM 确定嵌套关系,但它们并不直接适用于访问控制,并且本质上与单个 Java 语言概念相关联。
JVM对嵌套成员的访问控制改动
为了允许更广泛、更通用的嵌套概念,而不是简单的 Java 语言嵌套类型,并且为了有效的访问控制检查,建议修改类文件格式以定义两个新属性。 一个嵌套成员(通常是顶级类)被指定为嵌套主机,并包含一个属性 (NestMembers) 来标识其他静态已知的嵌套成员。 每个其他嵌套成员都有一个属性 (NestHost) 来标识其嵌套主机。
我们调整了JVM访问规则,增加了如下条目(to JVMS 5.4.4):
一个field或method R可以被class或interface D访问,当且仅当如下任一条件为真:
- ……
- R是私有的,并且声明在另一个class或interface C中,并且C和D是nestmates
嵌套成员反射API
正因Java引入了新的类文件属性,那么惯常地Java会提供新的反射机制来检查或查询这些属性。
引入了三个方法java.lang.Class: getNestHost, getNestMembers, and isNestmateOf。
309: Dynamic Class-File Constants(动态的类文件常量)
扩展 Java 类文件格式以支持新的常量池形式 CONSTANT_Dynamic。
Loading a CONSTANT_Dynamic will delegate creation to a bootstrap method, just as linking an invokedynamic call site delegates linkage to a bootstrap method.
invokedynamic的协议设计者(例如 Java 8 中添加的 LambdaMetafactory)经常需要根据现有常量集对行为进行编码, 这反过来又需要在引导程序本身中进行额外的容易出错的验证和提取逻辑。 更丰富、更灵活、更高度类型化的常量消除了invokedynamic协议开发中的挣扎,并促进和简化了编译器逻辑。
CONSTANT_Dynamic还在发展,未来还有一些工作需要做。
315: Improve Aarch64 Intrinsics(优化Aarch64内在函数)
改进现有的字符串和数组内在函数,并在 AArch64 处理器上为 java.lang.Math 包下的 sin,cos 和 log 函数实现新的内在函数。