转换Arrays.asList导致异常:java.util.Arrays $ ArrayList无法强制转换为java.util.ArrayList

Dan*_*ree 38 java arrays casting arraylist multidimensional-array

我是Java新手,我试图理解为什么第一个代码片段不会导致此异常,但第二个代码片段会导致此异常.由于在两种情况下都将字符串数组传递给Arrays.asList,因此两个片段是否都不会产生异常或不产生异常?

Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
Run Code Online (Sandbox Code Playgroud)

第一个片段(没有例外):

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));
Run Code Online (Sandbox Code Playgroud)

第二个片段(导致以上异常):

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

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

Wal*_*inz 30

对我来说(使用Java 1.6.0_26),第一个片段提供与第二个片段相同的异常.原因是该Arrays.asList(..)方法只返回一个List,不一定是一个ArrayList.因为你真的不知道该方法的类型(或实现)List返回,所以你的强制转换ArrayList<String>是不安全的.结果是它可能会或可能不会按预期工作.从编码风格的角度来看,一个很好的解决方法是将您的stuff声明更改为:

List<List<String>> stuff = new ArrayList<List<String>>();
Run Code Online (Sandbox Code Playgroud)

这将允许添加方法中的任何内容Arrays.asList(..).

  • 这个答案帮助我理解其他答案关于编码到接口而不是实现的内容以及我的转换是如何不安全的。 (2认同)

ada*_*shr 10

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

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

由于错误明确指出,该类java.util.ArrayList与嵌套静态类不同java.util.Arrays.ArrayList.因此例外.我们通过使用a包装返回的列表来克服这个问题java.util.ArrayList.


Boh*_*ian 10

问题是您指定要包含的列表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));
Run Code Online (Sandbox Code Playgroud)

我测试了这段代码,它运行没有错误.


Sri*_*n.S 8

无需手动投射.这个简单的代码可以帮到你,

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