我是Java新手,我试图理解为什么第一个代码段不会导致此异常,但第二个代码段会。因为字符串数组被传递给数组。在这两种情况下,两个片段不都应该产生异常还是不产生异常?
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
的类型(或的实现),所以对ArrayList<String>
的强制转换是不安全的。结果是,它可能会或可能不会像预期的那样工作。从编码风格的角度来看,解决这个问题的一个好方法是将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
-并且通过暗示没有其他列表实现。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));
我已经测试了这段代码,它运行没有错误。
无需手动强制转换。这段简单的代码可以帮助你,
List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
使用调试器,我确定Array.asList(titles)返回"Arrays$ArrayList"(即Arrays类的内部类)而不是java.util.ArrayList。
最好使用表达式左侧的接口,在本例中是List而不是具体的ArrayList。
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((List<String>) Arrays.asList(titles));
如果你想使用你的属性作为ArrayList<'T'>你只需要在那里声明并创建一个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;
}
初始化变量并使用方法[addAll (Collection Collection)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))
首先,Arrays.asList()不应该被强制转换为ArrayList。其次,由于泛型被引入到java编程语言中,所以在使用遗留的、泛型之前的api时,强制类型转换仍然是相关的。
第三,绝不在赋值操作符的左侧使用具体类。最后,输入
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));