列出为什么lambda不声明在其中使用的变量就可以工作?(爪哇)
下面是一个代码示例,它似乎正在工作,但我不明白为什么:
public static void replaceElements(List<Integer> list, int operator) {
list.replaceAll(element -> element % operator);
}
Java如何知道变量元素意味着列表元素?尽管javadoc说参数必须是一元运算符,为什么replaceAll方法仍然有效
default void replaceAll(UnaryOperator<E> operator)
我试图通过一步一步地调试来理解它,但没有多大帮助。谢谢你的回答
# 1 楼答案
它不在乎它是列表的元素,但是因为
List
接口被声明为List<E>
,其中E
是元素的类型,当replaceAll
方法声明它需要UnaryOperator<E>
时,Java编译器可以推断您必须向它传递UnaryOperator<Integer>
由于编译器知道您确实需要一个
UnaryOperator<Integer>
,并且UnaryOperator
只有一个抽象方法(称为apply
),因此它会尝试查看您提供的lambda是否与该方法的签名匹配:编译器需要一个
UnaryOperator<Integer>
编译器尝试匹配
Integer apply(Integer)
(一种将Integer
作为参数并返回Integer
的方法)编译器查看lambda,它接受一个参数
element
,并发现如果它推断Integer element
,那么lambda表达式的值也将是一个匹配的Integer
,因此它将lambda转换为与以下代码等价的值:# 2 楼答案
UnaryOperator
是一个functional interface,因此,“可以使用lambda表达式创建函数接口的实例”它不知道。它只知道你传递了一个lambda,它接受一个输入
element
并返回一个结果,并且从泛型类型参数推断出类型为Integer
。是List
本身在其元素上迭代,并将此lambda应用于每个元素: