有 Java 编程相关的问题?

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

java使用两种类型向通用列表添加对象

我读了几篇文章,比如here,但我找不到解决问题的办法

为什么我不能添加d?它是对象的一个子类型。。。 d的类型:A<B<X>>

 List<A<B<? extends Object>>> rv=new LinkedList<>();
 rv.add(d); //not working

编辑

我试图简化这个问题。当我这样做时:

 A<B<?>> abcv=new A<B<String>>();

我得到错误:类型不匹配:无法从A<B<String>> to A<B<?>>转换

但是,字符串与“?”兼容那么为什么它不起作用呢?我想将元素添加到列表中,最后一个类型可以通过任何方式进行选择,如下所示:

List<A<B<?>>> rv=new LinkedList<>();
rv.add(new A<B<X>>());
rv.add(new A<B<String>>());
rv.add(new A<B<Integer>>());

共 (3) 个答案

  1. # 1 楼答案

    List<A<B<?>>> rv = new LinkedList<>();
    

    ??泛指任何类型
    例如:
    可以将任何类型的泛型列表分配给List<?>,但不能将任何类型的对象添加到列表中,因为编译器不知道它是什么类型,因为通配符(?)

            List<?> genericList1 = new ArrayList<String>();
            List<?> genericList2 = new ArrayList<Integer>();
            List<?> genericList3 = new ArrayList<X>();
    
    
     /** 
      * Compiler will allow to assign any type of generic list to List<?> 
      * but it will not allow to add.
      */
    
    genericList1.add("xyz"); // It will give compiler error
    

    <?>通配符允许分配任何类型的列表,但add()方法在该列表上无效,因为可能会将错误类型的内容放入集合中。由于通配符(?),编译器不知道要传递哪种类型

    如果您想将任何类型的对象添加到列表中,您可以像这样获取列表

            List<Object> rv = new LinkedList<>();
            rv.add(new A<B<X>>());
            rv.add(new A<B<String>>());
            rv.add(new A<B<Integer>>());
    

    现在编译器知道rv是只接受对象类型的列表,所以编译器不会抱怨任何事情

  2. # 2 楼答案

    List<SubClaz>在Java中不是List<SuperClaz>的子类型。这就是为什么使用通配符:List<SubClaz>List<? extends SuperClaz>的一个子类型

    现在来看你的A<B<?>> abcv=new A<B<String>>();示例:

    通过添加通配符,您使B<String>成为了B<?>的子类型,但是由于它们也被另一个类型A包装,我们回到了第一个问题:
    A<B<String>>不是A<B<?>>
    的子类型 (注意B<?>SuperClaz,在本例中B<String>SubClaz

    你可以用同样的方法解决这个问题;通过添加另一个通配符:
    A<B<String>>()A<? extends B<?>>的一个亚型

    请记住,这不允许您根据需要阅读或操作列表。搜索协方差和逆变换以获取更多详细信息。这里有一个很好的例子:http://bayou.io/draft/Capturing_Wildcards.html

  3. # 3 楼答案

    d应具有类型A<B<? extends Object>>或兼容类型