我是Java新手,我试图理解为什么第一个代码片段不会导致此异常,但第二个代码片段会导致此异常。由于在两种情况下都将字符串数组传递给Arrays.asList,因此两个片段是否都不会产生异常或不产生异常?
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。
答案 0 :(得分:31)
对我来说(使用Java 1.6.0_26),第一个片段提供与第二个片段相同的异常。原因是Arrays.asList(..)
方法只返回List
,不一定是ArrayList
。因为您实际上并不知道该方法返回的List
的类型(或 的实现),所以您对ArrayList<String>
的强制转换是不安全的。结果是它可能会或可能不会按预期工作。从编码风格的角度来看,一个很好的解决方法是将stuff
声明更改为:
List<List<String>> stuff = new ArrayList<List<String>>();
允许添加Arrays.asList(..)
方法中的任何内容。
答案 1 :(得分:10)
如果你这样做,你就不会得到任何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
包装返回的列表来克服这个问题。
答案 2 :(得分:10)
问题是您指定列表包含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));
我已经测试了这段代码,它运行时没有错误。
答案 3 :(得分:8)
无需手动投射。这个简单的代码可以帮到你,
List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
答案 4 :(得分:1)
使用调试器,我确定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));
答案 5 :(得分:1)
如果您想将您的属性用作ArrayList&lt;&#39; T&#39;&gt;你只需要在那里声明并创建一个吸气剂。
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))
答案 6 :(得分:0)
首先,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));
并且快乐。