簡體   English   中英

Java 8下限有界通配符

[英]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綁定確保。

對象實例總是具有某些具體類型的類型參數,如ObjectString 只有引用可以具有通配符類型的類型參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM