[英]Java 8 Functional interface assignment context
問題是關於功能接口的分配上下文-
Predicate<String> p = String::isEmpty;
在 String 類中的isEmpty
方法聲明是 - public boolean isEmpty(){}
。
如果我嘗試在自定義類中聲明相同的 -
class Test{
public boolean isEmpty(){
...
}
}
並進行相同的分配 -
Predicate<String> p = Test::isEmpty;
這將是編譯錯誤 -
類型 Test 未定義適用於此處的 isEmpty(String)
Predicate<T>
表示一個參數的謂詞(布爾值函數),函數方法是boolean test(T t){}
。
有什么解釋嗎? 我錯過了什么嗎?
你應該有:
Predicate<Test> p = Test::isEmpty;
並不是
Predicate<String> p = Test::isEmpty;
沒有字符串
class Test {
public boolean isEmpty(){
...
}
}
那么為什么要有Predicate<String>
呢?
請參閱方法參考教程。 您在這里擁有的是第三種情況“對特定類型的任意對象的實例方法的引用”。
擁有
Predicate<String> p = String::isEmpty();
String s = "";
調用p.test(s);
與 callign s.isEmpty();
相同s.isEmpty();
所以這就是為什么你不能給一個String
作為參數來調用Test
的方法。
如果String
和Test
都使用boolean isEmpty()
方法實現接口Empty
,然后使用Predicate<Empty>
,那么就有可能擁有一個公共Predicate
。 然后p.test(string)
和p.test(test)
都可以工作; 否則不會,Java 具有強類型並且不支持鴨子類型。
可以通過幾種方式使用方法引用。 它可以捕獲要調用的實例。 它可以指應該在功能接口提供的參數上調用的方法(您的第一個示例)。 它也可以用作調用目標,其中函數接口中的參數作為參數傳遞給引用的方法調用(您的第二個示例)。
Predicate
接受任何泛型類型參數的參數。 您提供的方法引用必須能夠用它做一些事情。
我想添加到@m3th0dman 的答案中。
您確實可以使用Test
類的方法引用來定義Predicate<String>
。 實現方法是將isEmpty
方法定義為靜態方法並具有String
參數。
public class Test
{
public static boolean isEmpty (String s)
{
return s.length() == 0;
}
public static void main (String[] args)
{
Predicate<String> p = Test::isEmpty;
System.out.println(p.test("ff"));
System.out.println(p.test(""));
}
}
當你使用Predicate<String>
然后只的方法參考String
是可接受的。
要提供Test
類的方法引用,您將需要Predicate<Test>
因此代碼應該是:
Predicate<Test> p = Test::isEmpty;
代替
Predicate<String> p = Test::isEmpty;
為了使我的觀點更清楚,請考慮以下代碼:-
public static void main(String args[]){
Predicate<String> p;
p = String::isEmpty;
Predicate<Test> q;
q = Test::isEmpty;
}
interface Predicate<T>{
public boolean test(T t);
}
class Test{
public boolean isEmpty(){
return true;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.