public class SomeClass{
public static int someFunction(int a) {
return a;
}
public static void main(String[] args) {
Consumer<Integer> c = SomeClass::someFunction;
}
}
我不明白为什么:Consumer<Integer> c = SomeClass::someFunction;
不产生编译错误,因为函数someFunction是一个带返回值的方法,而Consumer表示没有返回值的方法
答案 0 :(得分:26)
来自the spec:
如果lambda的主体是一个语句表达式(即,一个 表达可以作为一个声明独立存在),它是 与产生空白的函数类型兼容; 任何结果都是简单的 丢弃。强>
方法参考也是如此。
这种方式更灵活。假设在正常调用方法时不使用返回值是一个编译器错误 - 那将是令人难以置信的烦人的。你最终不得不使用你在某些情况下并不关心的伪变量。
public class SomeClass
{
public static int someFunction(int a) {
return a;
}
public static void main(String[] args) {
someFunction(3); // "error" - ignoring return type
int unused = someFunction(3); // "success"
}
}
如果您想要接受完整的正式定义,请参阅15.13.2. Type of a Method Reference。
答案 1 :(得分:12)
这称为特殊void compatibility rule
。例如,您实际关注List#add
返回类型的次数是多少?即使它确实返回true/false
。
这里几乎相同,你可以调用一个方法,但忽略它的结果。如果你将你的消费者重写为lambda表达式,那就更有意义了:
Consumer<Integer> c = x -> {
SomeClass.someFunction(x);
return;
}
如果我从JLS中正确记得,那么只允许使用某些类型。
increment/decrement operations
method invocation
assignment
instance creation