铸造Arrays.asList导致exception:java.util.Arrays $ ArrayList不能转换为java.util.ArrayList

我是新来的Java,并试图了解为什么第一个代码片段不会导致此exception,但第二个。 既然在这两种情况下都将string数组传递给Arrays.asList,那么这两个片段是不是应该产生一个exception呢?

Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList 

第一个片段(不会导致例外):

 ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>(); String line = "a,b,cdef,g"; String delim = ","; String[] pieces = line.split(delim); stuff.add((ArrayList<String>) Arrays.asList(pieces)); 

第二个片段(导致以上例外):

 ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>(); String[] titles = {"ticker", "grade", "score"}; stuff.add((ArrayList<String>) Arrays.asList(titles)); 

如果相关,我在Eclipse Helios中使用JavaSE 1.6。

对于我(使用Java 1.6.0_26),第一个片段给出了与第二个片段相同的例外。 原因是Arrays.asList(..)方法只返回一个List ,不一定是一个ArrayList 。 因为您不知道该方法返回的Listtypes(或实现 ),所以将其转换为ArrayList<String>是不安全的。 结果是它可能会或可能不会按预期工作。 从编码风格的angular度来看,一个很好的解决办法是将你的stuff声明改为:

 List<List<String>> stuff = new ArrayList<List<String>>(); 

这将允许添加任何来自Arrays.asList(..)方法。

如果你这样做,你将不会得到任何CCE:

 ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>(); String[] titles = {"ticker", "grade", "score"}; stuff.add(new ArrayList<String>(Arrays.asList(titles))); 

正如错误清楚地表明的那样,类java.util.ArrayList与嵌套的静态类java.util.Arrays.ArrayList 。 因此例外。 我们通过使用java.util.ArrayList封装返回的列表来克服这个问题。

问题是你指定你的列表包含ArrayLists – 并暗示没有其他List实现Arrays.asList()根据数组参数的实现返回它自己的List实现,它可能不是一个ArrayList。 那是你的问题。

更广泛地说,你有一个经典的代码风格问题:你应该指的是抽象接口 (即List ),而不是具体的实现(即ArrayList )。 以下是您的代码的外观:

 List<List<String>> stuff = new ArrayList<List<String>>(); String[] titles = { "ticker", "grade", "score" }; stuff.add((List<String>) Arrays.asList(titles)); 

我已经testing了这个代码,它运行没有错误。

不需要手动投射。 这个简单的代码可以帮助你,

 List stuff = new ArrayList(); String line = "a,b,cdef,g"; String delim = ","; stuff.addAll(Arrays.asList(line.split(delim))); 

使用debugging器,我确定Array.asList(titles)返回一个“Arrays $ ArrayList”(即Arrays类的内部类)而不是java.util.ArrayList。

最好使用expression式左侧的接口,在这种情况下,使用List而不是具体的ArrayList。 这工作正常:

  List<List<String>> stuff = new ArrayList<List<String>>(); String[] titles = {"ticker", "grade", "score"}; stuff.add((List<String>) Arrays.asList(titles)); 

如果你想用你的属性作为ArrayList <'T'>,你只需要在那里声明并创build一个getter。

  private static ArrayList<String> bandsArrayList; public ArrayList<String> getBandsArrayList() { if (bandsArrayList == null) { bandsArrayList = new ArrayList<>(); String[] bands = {"Metallica", "Iron Maiden", "Nirvana"}; bandsArrayList.addAll(Arrays.asList(bands)); } return bandsArrayList; } 

初始化variables并使用方法[addAll(Collection collection)]( http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll (java.util.Collection))

首先,Arrays.asList()不应该被转换成ArrayList。 其次,由于generics被引入到java编程语言中,所以在使用传统的genericsAPI时,铸造仍然是相关的。

第三, 从不使用赋值运算符左侧的具体类。

底线,说

 List<List<String>> stuff = new ArrayList<List<String>>(); String line = "a,b,cdef,g"; String delim = ","; String[] pieces = line.split(delim); stuff.add(Arrays.asList(pieces)); List<List<String>> stuff = new ArrayList<List<String>>(); String[] titles = {"ticker", "grade", "score"}; stuff.add(Arrays.asList(titles)); 

而且要快乐。