List <string>无法转换为List <! - ? - >

时间:2016-05-26 16:28:30

标签: java generics

我有一个构建器类,其方法采用未知类型的列表

public class A{
    private List<D<?>> data;
    public void setData(List<D<?>> data){
        this.data=data;
    }
}
public class D<T>{
        private List<T> data;
        public void setData(List<T> data){
            this.data=data;
        }
    }

然后在我的来电课上我有:

    public class B{
        private A a;

        public void apply(A a, List<D<String>> list){
            a.setData(list); //It shows an error
        }
    }

显示以下错误:

  

List<String>无法转换为List<?>

我对未知类型的理解是它应该允许这样的基本内容。它们都是java.util.List

有人可以解释为什么会出现这种情况以及解决方法是什么?

3 个答案:

答案 0 :(得分:2)

<强>解释

如果有,

public void apply(A a, List<D<String>> list){
    a.setData(list); //It shows an error
}

它总是限制D实例的类型在String的上下文中应始终为apply()。因为我们在类a的{​​{1}}实例中实际拥有的内容可能是A。编译器会看到此冲突并且不允许编译。

<强>修正:

List<D<Integer>>

因为您可以在班级public void apply(A a, List<D<?>> list){ a.setData(list); } 中为T添加任何类型。 无界类型参数。

因此,您可以实例化D个实例,如下所示:

D

根据D<Integer> intD = new D<Integer>(); D<String> stringD = new D<String>(); 的类声明(由于Unbounded类型参数),所有这些都是完全可以接受的。

如果我们采用D个实例,则其stringDList。 与String实例相同,它的intDList

答案 1 :(得分:1)

正确输入解决方法:

class A{
    private List<? extends D<?>> data;
    public void setData(List<? extends D<?>> data){
        this.data=data;
    }
}

class A<T> {
    private List<D<T>> data;
    public void setData(List<D<T>> data){
        this.data=data;
    }
}
class B{
    private A<String> a;

    public void apply(A<String> a, List<D<String>> list){
        a.setData(list);
    }
}

答案 2 :(得分:0)

什么

public void apply(A a, List<D<String>> list){
    a.setData(list); // List<D<String>> cannot be converted to List<D<?>>
}

为什么

如果您被允许转换/转换List<D<String>>List<D<?>>,那么您可以在列表中添加D<Integer>,因为它允许包含任何D类型,但任何引用该列表的代码都会有一个包含D<Integer>的列表,只有D<String>时才会显示。

解决方法

如上所述,你不能直接投射到List<D<?>>,但你可以使用(我称之为)“魔法双重投射”;首先到List<?> 然后List<D<?>>

a.setData((List<D<?>>)(List<?>)list); // compiles OK!

当然这是一个不安全的演员,所以你应该确保这样做不会引起问题。