JVM 规范 (5.4.3.3) 描述了如何为方法引用完成方法解析。如果它在一个类或其父类(super class)中找不到方法,它会尝试在超接口(interface)中找到该方法。
这是什么原因?由超接口(interface)声明的方法不会作为接口(interface)方法引用而不是方法引用列在常量池中吗?
我的理解是方法引用用于 invokevirtual
操作,而接口(interface)方法 refs 用于 invokeinterface
操作。我看不出如何使用 invokevirtual <methodref>
调用接口(interface)方法。 .
最佳答案
为什么不?
您可以调用 .stream()
在 ArrayList<>
正好。事实上,下面的片段
ArrayList<Object> arr = new ArrayList<>();
arr.stream();
将被编译为
0: new #16 // class java/util/ArrayList
3: dup
4: invokespecial #18 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #19 // Method java/util/ArrayList.stream:()Ljava/util/stream/Stream;
但是
ArrayList<>
(或其任何父类(super class))没有 .stream()
方法。使用的方法实现来自
interface Collection
:default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
但是,如果在任何时候,
ArrayList<>
决定它可以提供更好的.stream()
方法,那么你不想再次编译你的代码。还有
.stream()
的实现(或非实现)方法会泄漏,最好避免这种情况。
关于java - 为什么JVM在解析非接口(interface)方法时会考虑超接口(interface)? (JVM 5.4.3.3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61394872/