我尝试用谷歌搜索,但没有找到有关下一个的任何详细信息:
在 11 之前的 java 中,我们有编译器添加的合成方法,用于绑定外部类和内部类的私有字段。听起来很合乎逻辑,因为编译后内部类包含到外部类的链接以访问它。因此,为了访问私有成员,创建了一种合成吸气剂。
问题是:java-11+如何处理呢?合成方法被删除。他们如何实现私有化?
因为Java虚拟机在Java 11中进行了更新,允许“直接”访问外部类中的私有字段。
首先,请注意添加了4.7.28和4.7.29节,它们描述了类文件格式中的NestHost和属性。NestMembers例如,当您编译这样的嵌套类时:
public class Outer {
private int x;
public class Inner {
public void foo() {
System.out.println(x);
}
}
}
Run Code Online (Sandbox Code Playgroud)
NestHostOuter$Inner.class 文件的属性将记录其外部类Outer。而NestMembersOuter.class文件的属性会记录内部类,Outer$Inner。
其次,在“访问控制”部分中添加了更多段落,以利用NestHost和NestMembers属性。Java 11 中是这么说的:
当且仅当满足以下任一条件时,类或接口 D 才能访问字段或方法 R:
- [...]
- 根据下面的嵌套测试, R 是
private由与 D 属于同一嵌套的类或接口 C 声明的。如果 D 无法访问 R,则:
- [...]
- 如果 R 为
private,则 Nestmate 测试失败,访问控制也会因同样的原因失败。
而在 Java 10 中,它只说:
当且仅当满足以下任一条件时,类或接口 D 才能访问字段或方法 R:
- [...]
- R 是
private并且在 D 中声明。
“同屋测试”有点长,这里就不引用了。重要的是它考虑了NestHost班级的情况。
回到上面的代码,在 Java 10 中,JVM 的访问控制规则规定x不能从 访问它Inner,因此编译器必须合成一个额外的方法才能Inner访问它。在 Java 11 中,现在的规则规定可以x从 访问Inner,因此对 的访问x可以简单地编译为getfield指令。