在Java 8中,给定程序包Super
中的超类a
和程序包Sub
中的子类b
,它们具有内部类SubInner
:
// 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::setValue
,则代码不会编译,并且错误似乎与运行时错误一致:setValue
在a.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
答案 0 :(得分:12)
非常像this bug,它是固定的...
由于错误状态,我本地没有Java-9来确认它确实在Java-9中已修复;但在java-11和java-12下工作正常。 javac/java
处理lambda /方法引用并不是第一次出现异常。通常,lambda是方法引用的解决方法,反之亦然。