为什么在尝试使用内部类中的方法引用来调用超类的受保护方法时,我会得到 BootstrapMethodError?

2022-09-04 21:19:44

在Java 8中,给定一个包中的超类和一个包中的子类,谁有一个内部类:SuperaSubbSubInner

// Super.java
package a;

public abstract class Super {
   private long value;
   protected final void setValue(long value) {
      this.value = value;
   }
}

//Sub.java
package b;

public class Sub extends Super {
  public void foo() {
    new SubInner().foo();
  }
  private class SubInner {
    void foo() {
      Optional.of(1L).ifPresent(Sub.this::setValue); // Will throw IllegalAccessError at runtime.
      Optional.of(1L).ifPresent(t -> setValue(t)); // However, lambda works.
      setValue(1L); // also works.
    }
  }
}

我的问题是,为什么在这种情况下方法引用无法正常工作,而普通方法调用可以访问超类方法?setValue

另外,如果我尝试这样做,代码无法编译,并且错误似乎与运行时错误一致:在 中具有受保护的访问权限。Sub.super::setValuesetValuea.Super

Exception in thread "main" java.lang.BootstrapMethodError: java.lang.IllegalAccessError: tried to access method a.Super.setValue(J)V from class b.Sub$SubInner
    at b.Sub$SubInner.foo(Sub.java:14)
    at b.Sub.foo(Sub.java:10)
    at b.Sub.main(Sub.java:22)
Caused by: java.lang.IllegalAccessError: tried to access method a.Super.setValue(J)V from class b.Sub$SubInner
    at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
    at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975)
    at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000)
    at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394)
    at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750)
    at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477)
    ... 3 more

答案 1

它非常像这个错误,这是修复的...

我没有本地的java-9来确认它确实在java-9中得到了修复,正如错误所述;但在java-11和java-12下工作得很好。这不是第一次在如何处理 lambda/方法引用方面出现异常;通常,lambda 是方法引用的解决方法,反之亦然。javac/java


答案 2

推荐