簡體   English   中英

為什么我不能將T類型的對象傳遞給該類型對象的方法 <? extends T> ?

[英]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.

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