[英]I think that the Stream.filter() is not showing compile time error even with an invalid predicate
在下面的代碼中,我有這一行: stream.filter(Data::isEven);
我正在使用filter()
並且filter()
接受Predicate
接口作為參數。 我們都知道Predicate
有一種帶有簽名的方法: public boolean test(T 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;
}
}
事實是, Data::isEven
是一個等效於data -> data.isEven()
謂詞的方法引用:
Predicate<Data> predicate = data -> data.isEven();
// is the same as
Predicate<Data> predicate= Data::isEven;
JLS 15.13
對此進行了描述:
實例方法(第15.12.4.1節)的目標引用可以由方法引用表達式使用
ExpressionName
,Primary
或super
,或者可以在以后調用該方法時提供。....
方法引用表達式的求值將生成功能接口類型的實例(第9.8節)。 方法參考評估不會導致執行相應的方法; 相反,這可能在以后調用功能接口的適當方法時發生。
在您的情況下, Data::isEven
是對Data
對象的實例方法isEven
的引用。
Data::isEven
是一個Predicate
。
要調用此方法,您必須傳遞值,例如: myData.isEven()
。 這與isEven(myData)
。 因此,區別僅在於語法(點之前或括號內的參數),但在語義上是相同的。
因此isEven
是Predicate<Data>
因為它接受Data
並返回Boolean
。
正如其他人所寫,“ Data :: isEven”或“ data-> data.isEven()”在此處是謂詞。 當我們調用該謂詞的測試方法時,我們會將數據實例(您有此類實例的流)作為參數傳遞給該實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.