Java 我认为Stream.filter()即使使用了无效的谓词,也没有显示编译时错误
在下面的代码中,我有一行:Java 我认为Stream.filter()即使使用了无效的谓词,也没有显示编译时错误,java,lambda,java-8,java-stream,method-reference,Java,Lambda,Java 8,Java Stream,Method Reference,在下面的代码中,我有一行:stream.filter(Data::isEven) 我正在使用一个filter()和一个filter()接受一个谓词接口作为参数。我们都知道,谓词有一个带有签名的方法:公共布尔测试(T) 它接受一个参数并返回一个布尔值 我理解不接受任何参数的isEven()方法不是有效的谓词,因为与test()方法不同,它不接受任何参数,所以为什么我的代码没有显示编译时错误 import java.util.stream.Stream; public class Main App
stream.filter(Data::isEven)代码>
我正在使用一个filter()
和一个filter()
接受一个谓词
接口作为参数。我们都知道,谓词
有一个带有签名的方法:公共布尔测试(T)代码>
它接受一个参数并返回一个布尔值
我理解不接受任何参数的isEven()
方法不是有效的谓词,因为与test()
方法不同,它不接受任何参数,所以为什么我的代码没有显示编译时错误
import java.util.stream.Stream;
public class Main App {
public static void main(String args[]) {
Stream<Data> stream =
Stream.of(new Data(4), new Data(1));
stream.filter(Data::isEven); // should throw compile error but doesn't
}
}
class Data{
int i;
public Data(int i) {
this.i=i;
}
public boolean isEven() {
return i%2==0;
}
}
import java.util.stream.stream;
公共类主应用程序{
公共静态void main(字符串参数[]){
溪流=
流(新数据(4)、新数据(1));
stream.filter(Data::isEven);//应该抛出编译错误,但不会
}
}
类数据{
int i;
公共数据(int i){
这个。i=i;
}
公共布尔值isEven(){
返回i%2==0;
}
}
问题是Data::isEven
是一个方法引用,相当于Data->Data.isEven()
谓词:
Predicate<Data> predicate = data -> data.isEven();
// is the same as
Predicate<Data> predicate= Data::isEven;
Predicate=data->data.isEven();
//与
谓词=数据::isEven;
这在以下章节中进行了描述:
实例方法(§15.12.4.1)的目标引用可由方法引用表达式使用ExpressionName
、Primary
或super
提供,也可在调用该方法后提供
方法引用表达式的求值产生函数接口类型的实例(§9.8)。方法参考评估不会导致相应方法的执行;相反,这可能会在稍后调用函数接口的适当方法时发生
在您的例子中,Data::isEven
是对Data
对象的实例方法isEven
的引用。Data::isEven
是一个谓词
要调用此方法,必须传递值,例如:myData.isEven()
。
这与isEven(myData)
相同。所以区别只是在语法上(参数在点之前或括号内),但在语义上是相同的
因此,isEven
是一个谓词
,因为它接受数据
,并返回布尔值
,,就像其他人写的“Data::isEven”或“Data->Data.isEven()是这里的谓词一样。当我们调用这个谓词的test方法时,我们将数据实例(您有一个这样的实例流)作为参数传递到那里。isEven()方法与谓词接口中的test()方法不匹配。我无法理解的是,编译器是如何监督这种不匹配的?其他答案会不断以高速更新。在某些时候,我的答案可能会在这样的更新中失去意义:-)每当您看到ClassName::method
,第一个参数就会转换为方法调用的目标。谢谢您的解释很有帮助。我接受了答案。