java forEach参数与使用者功能接口参数不匹配,但代码仍然可以编译,为什么?
我正在学习OCP考试,我注意到下面的一段代码,其中在DoubleStream上调用的forEach方法的参数必须与DoubleConsumer函数接口的参数匹配,但是lambda不匹配所需的类型,为什么它仍然编译
DoubleStream.of(3.14159, 2.71828)
.forEach(c -> service.submit(
() -> System.out.println(10*c)
));
DoubleConsumer(接受Double类型的参数,返回类型为void),但是这个forEach的返回类型为Future<?>
where?表示可运行lambda的返回类型,它是void,Future-这不是void。我这么说是因为退货服务的类型。提交(…)它不是空的,为什么要编译这段代码
# 1 楼答案
lambda表达式的返回类型和目标函数接口类型的函数类型的返回类型必须完全匹配,这并不是真的。Java语言规范规定
void
是一种特殊情况在§15.27.3中,它说:
我们处在一个调用上下文中
T
是DoubleConsumer
。从它派生的地面目标类型也是DoubleConsumer
,其函数类型是一个方法,它接受double
并返回void
让我们看看“一致”是什么意思:
“假定具有与函数类型的参数类型相同的类型”基本上意味着没有显式写出
c
的类型语句表达式只是一个表达式,可以通过在末尾添加
;
来生成语句。任何方法调用都是一个语句表达式。这就是submit
调用编译的原因5
不是语句表达式(但它是一个表达式),因此c -> 5
不编译如果你想一想,如果你说返回某物的方法不应该被分配给函数类型为void返回类型的函数接口,那么你是说“接受
A
并给出B
的函数”不是一种A
的消费者。然而,他们显然是A
的消费者!毕竟,他们接受了A
。某物是否是A
的消费者并不取决于它们生产的因此,Java就是为了实现这一点而设计的