根据这个article,方法引用被定义为一个没有被执行的引用的方法或构造函数,任何人都可以解释这是怎么可能的?
例如:
public void main String(args[]) {
List<Integer> numbers = Arrays.asList(1, 2, 3);
// Below is a method reference that is referenced and being executed on run (prints the numbers!!)
numbers.forEach(System.out::println);
}
如果有人能够解释在没有被执行的情况下引用了哪些陈述&#39;意思是,非常感谢:)
答案 0 :(得分:2)
当您致电numbers.forEach(System.out::println)
时,您会引用System.out::println
方法,但不会执行该方法。例如,如果numbers
列表为空,则永远不会执行此方法。另一方面,有了这个方法引用,forEach
方法可以在内部调用此引用多次(在这种情况下:对于每个列表元素)。
当您使用等效的匿名类重写此代码时,可能会更容易理解:
numbers.forEach(new Consumer<Integer>() {
public void accept(Integer num) {
System.out.println(num);
}
});
在这里你可以看到方法引用实际上是Consumer
类型的辅助对象的创建,而没有实际调用引用的方法。
答案 1 :(得分:2)
您的陈述numbers.forEach(System.out::println);
是
Consumer<Integer> c=System.out::println;
numbers.forEach(c);
这应该更好地说明第一行创建对println
中找到的PrintWriter
实例的方法System.out
的引用,但不执行它。它不会打印任何东西 - 它甚至不知道要打印什么。要打印的对象是创建的Consumer
accept
方法的参数。
第二行numbers.forEach(c)
最终会打印每个数字,因为指定的Consumer
已创建为参考System.out::println
。 forEach
方法接收任意Consumer
并通过为每个元素调用所述accept
方法为每个元素执行封装操作,并将该元素作为参数传递。
当然,您可以内联变量c
获取原始语句numbers.forEach(System.out::println);
,但是,消费者创建和执行之间的差异不是那么明显,但也与此用例无关。通常,您可以使Consumer
比单个用例更长。