forEach()方法如何在Java 8中工作

Deb*_*Deb 1 java java-8

我正在写一个片段:

List<Integer> list=Arrays.toList(2,4,6,8);
list.forEach(i -> System.out.println(i));
Run Code Online (Sandbox Code Playgroud)

请在上面的代码片段中解释一下方法调用的流程.forEach()方法如何将参数传递给accept()方法?forEach()方法每次都调用accept方法吗?如果我错了,请纠正我.

i-> System.out.println(i)
Run Code Online (Sandbox Code Playgroud)

返回Consumer接口的对象.forEach()使用i作为参数调用该对象的accept()方法.

T.J*_*der 7

因为Consumer是一个功能接口,你的lambda函数可以隐式地满足它.所以,当你这样做

list.forEach(i -> System.out.println(i));
Run Code Online (Sandbox Code Playgroud)

你在概念上做什么(下面更多)是

list.forEach(new Consumer<String>() {
    @Override
    public void accept(String i) {
        System.out.println(i);
    }
});
Run Code Online (Sandbox Code Playgroud)

然后传入实例forEach,该实例为accept列表中的每个条目调用其方法.

根据您对该问题的评论:

我很困惑首先调用哪个方法.它是"forEach()"还是"accept()",因为它们都在努力收集!

事情的顺序是:

  • 创建匿名类的实例(实际上,通过invokedynamic操作)
  • forEach 被称为,传入该引用
  • forEach每次将一个列表项传递给它(它接收为)时,代码会重复调用 accepti

注意我在概念上说.编译器并不真正创建匿名类; 相反,调用的新字节码操作invokedynamic用于创建消费者实例.