JVM 规范 ( 5.4.3.3 ) 描述了如何为方法引用完成方法解析。如果在类或其超类中找不到方法,它会尝试在超接口中找到方法。
这是什么原因?由超接口声明的方法不会作为接口方法 ref 而不是方法 ref 列在常量池中吗?
我的理解是方法引用用于invokevirtual操作,而接口方法引用用于invokeinterface操作。我不知道如何使用invokevirtual <methodref>.
为什么不?
你可以调用.stream()一个ArrayList<>就好了。事实上,下面的片段
ArrayList<Object> arr = new ArrayList<>();
arr.stream();
Run Code Online (Sandbox Code Playgroud)
将被编译为
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;
Run Code Online (Sandbox Code Playgroud)
但是ArrayList<>(或任何它的超类)没有.stream()方法。
使用的方法实现来自interface Collection:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果在任何时候ArrayList<>决定它可以提供更好的.stream()方法,那么您就不想再次编译代码。
此外,该.stream()方法的实现(或非实现)会泄漏,最好避免这种情况。