为什么我不能将类型为T的对象传递给类型为<?的对象上的方法?延伸T>?

Mat*_*t H 1 java generics

在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

Ita*_*man 7

看看下面的程序

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!  
Run Code Online (Sandbox Code Playgroud)

如你所说,(A)行不编译.如果这一行是合法的,那么在运行时,程序会将一个Double对象传递给动态类型cn.set()所在的调用.cnCell<Integer>

当执行随后到达(B)时,ci.get()将返回一个Double对象---传递给(A)的对象---声明ciget()方法保证返回一个Integer.为了防止这一难题(这实际上打破了JVM的强类型哲学),编译器不允许分配T<? extends T>.