为什么 Java 编译器会为包私有超类型中定义的公共方法添加可见性桥接方法?

Raf*_*ter 5 java javac java-bridge-method

我想知道为什么Java编译器会在foo这里为该方法添加桥接方法:

public class Outer {

  class SuperClass {
    public void foo() { }
  }

  public class SubClass extends SuperClass { }
}
Run Code Online (Sandbox Code Playgroud)

foo方法被编译为publicSuperClass类型。然而,该SubClass方法将方法重新定义为通向相同方法的桥梁。我想知道为什么需要这座桥。

Raf*_*ter 3

添加此桥接方法的原因是 Java 反射 API 中的一个极端情况,如果IllegalAccessException不添加桥接方法,将导致出现问题。该错误记录在Oracle 的错误跟踪器中:

反思性的调用

Subclass.class.getMethod("foo").invoke(new Subclass())
Run Code Online (Sandbox Code Playgroud)

与没有桥接方法修复的情况相比,其他包无法正确处理,SuperClass因为 Java 运行时无法确定该foo方法的调用是否合法。反射会对方法的声明类型进行可见性检查,然后错误地得出该方法不可见且其调用非法的结论。

根据票证上的文档,没有更简单的解决方法。然而,即使在添加桥接方法之前,非反射调用也可以正常处理。