[英]Why can't I pass an object of type T to a method on an object of type <? extends T>?
在Java中,假設我有以下包含類Items列表的類Container:
public class Container<T>
{
private List<Item<? extends T>> items;
private T value;
public Container(T value)
{
this.value = value;
}
public void addItem(Item<? extends T> item)
{
items.add(item);
}
public void doActions()
{
for (Item<? extends T> item : items)
{
item.doAction(value);
}
}
}
public abstract class Item<T>
{
public abstract void doAction(T item);
}
Eclipse給出錯誤:項目類型中The method doAction(capture#1-of ? extends T) in the type Item is not applicable for the arguments (T)
我一直在閱讀泛型示例和各種文章,但是我仍然不知道為什么不允許這樣做。 Eclipse在建議的修復程序中也沒有提供任何有用的提示。 變量value
的類型為T,為什么不適用於? extends T
? extends T
?。
看下面的程序
public class Cell<T> {
private T value;
public void set(T t) { value = t; }
public T get() { return value; }
}
Cell<Integer> ci = new Cell<Integer>();
Cell<? extends Number> cn = ci;
cn.set(new Double(5.0)); // (A) <-- Compile error here
Integer n = ci.get(); // (B) Runtime error!
如您所說,(A)行不會編譯。 如果此行合法,則在運行時,程序會將Double
對象傳遞給cn.set()
調用,其中cn
的動態類型為Cell<Integer>
。
當執行隨后到達(B)時, ci.get()
將返回Double
對象-(A)中傳遞的對象--如果ci
的聲明表明其get()
方法可以保證返回,一個Integer
。 為了避免出現這種難題(這實際上打破了JVM的強類型哲學),編譯器禁止將T
分配給<? extends T>
<? extends T>
。
PECS-生產者擴展,消費者超級
將所有出現的extends
替換為聲明中的super
(包括在循環中省略的extends
),然后編譯:)
請參閱我的(僅!)博客文章 。 它並沒有直接討論“?extends T”的情況,但是在任何看到“?”的地方,只要想象它說“?extended Object”,它就應該變得清楚了。
基本上,您具有“擴展T的內容”的列表,但是您不知道在編譯時這些內容是什么。
邊界相反。 Item <X>的doAction可以采用X或X的子類。 現在? extends T
? extends T
意味着X是? extends T
的子類。因此,您要將T傳遞給期望X的項,X是T的子類,而不是相反。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.