有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法将实现接口A的对象添加到集合<?扩展A>

为什么我不能将a对象添加到集合中?因为B类是A的延伸

import java.util.*;

public class TestGeneric
{
  public static void main(String[] args)
  {
    Collection<? extends A> collection = new ArrayList<A>();
    A a = new B();
    collection.add(a);
  }

  private static class B implements A {
    public int getValue() { return 0; }
  }
}

interface A { int getValue(); }

共 (3) 个答案

  1. # 1 楼答案

    如果有<? extends A>,那么此时编译器不知道正在使用的A的子类是什么。因此,除了null之外,向集合中添加任何对象都是不安全的

    你不能向List<? extends T>添加任何对象,因为你不能保证它真正指向的是什么类型的列表,所以你不能保证该对象在该列表中是允许的。唯一的“保证”是你只能从中阅读,你会得到一个Tsubclass of T

    List<? extends Number>可以通过以下三种方式实现:

    List<? extends Number> list = new ArrayList<Number>();//数字“扩展”数字 List<? extends Number> list = new ArrayList<Integer>();//整数扩展数字 List<? extends Number> list = new ArrayList<Double>();//Double扩展数字

    因此,如果它是new ArrayList<Double>(),并且您正在添加integer,那么这是一个错误,所以编译器可以安全地将访问限制为只读取而不添加

    添加也是安全的,因为我们知道父类,因此我们可以将任何子类分配给父类引用,如下所示:

    这是安全的

    因此,在List<? extends Number>中,我们知道集合中的所有元素都在以某种方式扩展Number,因此我们可以读取它,因为我们可以将子类的实例分配给父类引用

  2. # 2 楼答案

    原因如下:

    Collection<? extends A> coll = new ArrayList<C>(); // C extends A
    
    coll.add(new B()); // B extends A, but doesn't extend C. Oops.
    

    然而,由于编译器知道coll只有扩展A的元素,所以仍然可以按原样检索它们

    A myA = coll.get();  // No problem, it might be B or C, but they both extend A
    
  3. # 3 楼答案

    简短的解释:

    <? extends A>意思是:一些特定但未知的类型扩展了A。可能是A本身或其任何亚型。因此,不能在此集合中插入任何元素:编译器无法知道add(object)方法的参数的合法类型