Java:从列表中强制转换<;B>;列出<;A>;B何时实现A?

Java:从列表中强制转换<;B>;列出<;A>;B何时实现A?,java,generics,list,inheritance,casting,Java,Generics,List,Inheritance,Casting,我定义了以下类和接口: public interface A { } public class B implements A { } 我有一个列表的B对象,我需要将其转换为列表的a对象: List<B> listB = new List<B>(); listB.add(new B()); // dummy data listB.add(new B()); // dummy data listB.add(new B()); // dummy data List&l

我定义了以下类和接口:

public interface A {
}

public class B implements A {
}
我有一个
列表
B
对象,我需要将其转换为
列表
a
对象:

List<B> listB = new List<B>();
listB.add(new B());  // dummy data
listB.add(new B());  // dummy data
listB.add(new B()); // dummy data

List<A> listA = (List<A>) listB;
List listB=new List();
listB.add(新的B());//虚拟数据
listB.add(新的B());//虚拟数据
listB.add(新的B());//虚拟数据
List listA=(List)listB;
上面的最后一行导致编译错误“无法从一个列表转换到另一个列表”。我尝试用以下方法来解决这个问题:

List<A> listA = Arrays.asList((A[]) listB.toArray());
List listA=Arrays.asList((A[])listB.toArray();

不幸的是,这会抛出一个
ClassCastException
。有人知道我如何解决这个问题吗?

你不能那样施放它。创建一个新的:

List<A> listA = new ArrayList<A>(listB);
List listA=新的数组列表(listB);

构造函数使用
集合我确信您需要使整个列表(在那里进行奇怪的解析),并且在添加新的B对象时使用(A)强制转换它们


如果知道操作是安全的,您可以使用类型擦除。这将生成一个警告,您可以使用@SuppressWarnings关闭该警告

List<A> listA = (List) listB;
List listA=(List)listB;
编译器在普通转换中遇到困难的原因是,您现在可以添加一个类C,该类也实现了a。但您的原始列表已被更改,并且现在包含一个C,即使您已指定它不应该包含C。

list listA=(list)(list)listB;
List<A> listA = (List<A>)(List<?>) listB;

不推荐。

与其与语言功能作斗争,不如学会正确使用它

与其问如何使用不安全的强制转换来解决错误,不如先了解错误的原因;为什么您要求执行的操作不安全(因为您可以使用
listA
A
添加到列表中,然后使用
listB
将其作为
B
从列表中删除)

然后,您应该解释为什么您认为您的用例没有运行到不安全的场景中。因为这个问题的答案将给出一个提示,告诉你如何修改你的代码,使它能正确地与泛型一起工作


  • 如果您说它不是不安全的,因为您从未使用
    listA
    添加任何内容,那么您应该将
    listA
    的类型更改为
    List,这只是声明的问题。不要将listB声明为List,而是声明为List或List

    List<A> listB = new List<B>();
    listB.add(new B());  // dummy data
    listB.add(new B());  // dummy data
    listB.add(new B()); // dummy data
    
    List<A> listA = listB;
    
    List listB=new List();
    listB.add(新的B());//虚拟数据
    listB.add(新的B());//虚拟数据
    listB.add(新的B());//虚拟数据
    List listA=listB;
    
    就这么简单。 如果您想强制listB成为List(避免添加任何非B元素),您将被迫使用:

    List<A> listA = new ArrayList<A>(listB);
    
    List listA=新的数组列表(listB);
    

    但正如他们已经指出的,如果你被迫这样做,这不是一个好迹象。

    我们可以使用泛型和通配符来实现这一点。您可能无法创建
    List
    ,但创建类似
    List
    newlist()的内容是无效的<代码>列表
    是一个界面。这是很久以前的事了,我甚至不记得我在这个问题上想做什么了。但是感谢您的反馈,感谢+1提供适合语言的建议。乍一看,我认为这是一篇傲慢的RTFM帖子,但结果证明它真的很有洞察力和有用。谢谢你,newacct!
    List<A> listA = new ArrayList<A>(listB);
    
    List<B> bList = new ArrayList<B>();
    
    List<? extends A> aList = bList;