java 中发生了什么变化,因此合成方法被删除了?

the*_*aba 5 java

我尝试用谷歌搜索,但没有找到有关下一个的任何详细信息:

在 11 之前的 java 中,我们有编译器添加的合成方法,用于绑定外部类和内部类的私有字段。听起来很合乎逻辑,因为编译后内部类包含到外部类的链接以访问它。因此,为了访问私有成员,创建了一种合成吸气剂。

问题是:java-11+如何处理呢?合成方法被删除。他们如何实现私有化?

Swe*_*per 9

因为Java虚拟机在Java 11中进行了更新,允许“直接”访问外部类中的私有字段。

您可以比较JVMS 11JVMS 10

首先,请注意添加了4.7.284.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

其次,在“访问控制”部分中添加了更多段落,以利用NestHostNestMembers属性。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指令。