[英]Java 8 lower bounded wildcard
我正在准備OCP證書,我想到了一個較低的有界通配符的想法。 如果我理解正確的話,當我們想讓Java知道“有界類型”總是可以添加到我們的通用集合時,使用下限有界通配符。
例如:
public static void addInteger(List<? super Integer> list, Integer i)
{
list.add(i);
}
public static void main(String[] args)
{
List<Number> list = new ArrayList<>();
addInteger(list, 100);
addInteger(list, 200);
System.out.println(list); // [100,200]
}
由於“?super Integer”表示類型必須是Integer或其超類,因此在列表中添加Integer將適用於每種情況。
但是,此代碼仍然編譯並運行正常:
public static void main(String[] args)
{
Predicate<? super String> pred = s -> s.startsWith("M"); // still compiles
System.out.println(pred.test("Mon")); // Output true
}
現在我們有一個謂詞,它將采用1個參數,這是一個String或它的超類,但我們不確定它實際上是一個字符串與否(如果它只是一個對象怎么辦?)。 但是,我們仍然可以訪問startsWith()
方法,就像s
實際上是一個String。
為什么會這樣? 請向我解釋。
Predicate<? super String> pred
Predicate<? super String> pred
可以分配Predicate<String>
或Predicate<Object>
。 您正在為其分配一個允許的Predicate<String>
。 編譯器推斷s -> s.startsWith("M")
是一個Predicate<String>
因為你在lambda表達式中使用了String
方法。
例如,以下內容也將通過編譯:
Predicate<? super String> pred = (Object o) -> o.hashCode() > 0;
您還可以看到以下傳遞編譯:
Predicate<String> preds = s -> s.startsWith("M");
Predicate<Object> predo = (Object o) -> o.hashCode() > 0;
Predicate<? super String> pred = preds;
pred = predo;
即Predicate<? super String>
Predicate<? super String>
既可以分配Predicate<String>
,也可以分配Predicate<Object>
。
也就是說,注意pred.test()
只接受String
,而不接受任何Object
。 原因是pred
變量可以在運行時引用Predicate<Object>
或Predicate<String>
,並且兩者都只接受String
。
你似乎對Predicate
對象實例的類型(由lambda創建)和pred
類型(對該對象的引用)之間的區別感到困惑。
由lambda創建的Predicate
實例的類型為Predicate<String>
。
參考pred
的對象的類型是Predicate<? super String>
Predicate<? super String>
,因此可以分配Predicate<Object>
和Predicate<String>
類型的值。 但是謂詞的test
方法只能用String
對象調用!
那是什么? super String
? super String
綁定確保。
對象實例總是具有某些具體類型的類型參數,如Object
或String
。 只有引用可以具有通配符類型的類型參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.