铸造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
。 因为您不知道该方法返回的List
types(或实现 ),所以将其转换为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));
而且要快乐。