Java:当B实现A时,从List 转换为List

我定义了以下类和接口:

public interface A { } public class B implements A { } 

我有一个B对象List ,我需要将其转换为A对象List

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

上面的最后一行导致编译错误“无法从列表转换为列表”。 我尝试用以下方法解决这个问题:

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

不幸的是,抛出ClassCastException 。 有谁知道我怎么解决这个问题?

你不能这样投。 创建一个新的:

 List listA = new ArrayList(listB); 

构造函数采用Collection Collection 。 无论如何它将指向相同的参考。

您应该学会正确使用它,而不是与语言function作斗争。

而不是询问如何使用不安全的强制转换来解决错误,首先要了解为什么会出现错误是有益的; 为什么你要做的是不安全的(因为你可以使用listAA添加到列表中,然后使用listA将其作为B从列表中listB )。

然后,您应该解释为什么您认为您的用例不会遇到不安全的情况。 因为对此的回答将提示如何更改代码以使其与generics一起正常工作。

  • 如果你说它不是不安全的,因为你从不使用listA添加任何listA ,那么你应该将listA的类型listAList List 。 这样,您可以直接为其分配listB而不进行任何强制转换,并且您将无法使用listAnull除外)向其添加任何内容。
  • 如果你说它不是不安全的,因为你从来没有使用listB得到任何东西,那么为什么不首先将listB的类型listBList

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

 List listA = (List) listB; 

编译器在使用普通强制转换时遇到困难的原因是你现在可以添加一个同样实现A的C类。除非你的原始列表已被更改,现在包含一个C,即使你已经指定它不应该。

 List listA = (List)(List) listB; 

不建议。

我确定你需要制作整个列表List (在那里进行奇怪的解析),并在添加新的B对象时使用它们(A)

 listA.add( (A) new B()); // dummy data 

这只是一个宣言问题。 不要将listB声明为List,而是将其声明为List或List。

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

就如此容易。 如果要强制listB为List(避免添加任何非B元素),您将被迫使用:

 List listA = new ArrayList(listB); 

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

我们可以使用generics和通配符来实现这一点。 您可能无法创建List但创建类似List List将调用接口的所有方法,这对我认为最多。

创建新集合非常昂贵且不可取。 由于相同对象的引用将被传递到新集合中,因此附加列表创建步骤只是一个开销。

 List bList = new ArrayList(); List aList = bList;