转换 Arrays.asList 导致异常:java.util.Arrays$ArrayList 不能转换为 java.util.ArrayList
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6641006/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
casting Arrays.asList causing exception: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
提问by DannyTree
I'm new to Java and am trying to understand why the first code snippet doesn't cause this exception but the second one does. Since a string array is passed into Arrays.asList in both cases, shouldn't both snippets produce an exception or not produce an exception?
我是 Java 新手,我试图理解为什么第一个代码片段不会导致此异常,但第二个会导致此异常。由于在这两种情况下都将字符串数组传递到 Arrays.asList 中,两个片段不应该产生异常还是不产生异常?
Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
First snippet (causes no exception):
第一个片段(也不例外):
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));
Second snippet (causes above exception):
第二个片段(导致上述异常):
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((ArrayList<String>) Arrays.asList(titles));
If relevant, I'm using JavaSE 1.6 in Eclipse Helios.
如果相关,我将在 Eclipse Helios 中使用 JavaSE 1.6。
采纳答案by Waldheinz
For me (using Java 1.6.0_26), the first snippet gives the same exception as the second one. The reason is that the Arrays.asList(..)
method does only return a List
, not necessarily an ArrayList
. Because you don't really know what kind (or implementation of) of List
that method returns, your cast to ArrayList<String>
is not safe. The result is that it may or may not work as expected. From a coding style perspective, a good fix for this would be to change your stuff
declaration to:
对我来说(使用 Java 1.6.0_26),第一个片段给出了与第二个相同的异常。原因是该Arrays.asList(..)
方法只返回 a List
,不一定是 an ArrayList
。因为您并不真正知道该方法返回的类型(或实现)List
,所以您的强制转换ArrayList<String>
是不安全的。结果是它可能会或可能不会按预期工作。从编码风格的角度来看,一个很好的解决方法是将您的stuff
声明更改为:
List<List<String>> stuff = new ArrayList<List<String>>();
which will allow to add whatever comes out of the Arrays.asList(..)
method.
这将允许添加任何来自该Arrays.asList(..)
方法的内容。
回答by adarshr
If you do this, you won't get any CCE:
如果您这样做,您将不会获得任何 CCE:
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(new ArrayList<String>(Arrays.asList(titles)));
As the error clearly states, the class java.util.ArrayList
isn't the same as nested static class java.util.Arrays.ArrayList
. Hence the exception. We overcome this by wrapping the returned list using a java.util.ArrayList
.
正如错误明确指出的那样,该类java.util.ArrayList
与嵌套静态类不同java.util.Arrays.ArrayList
。因此例外。我们通过使用 a 包装返回的列表来克服这个问题java.util.ArrayList
。
回答by Bohemian
The problem is you specified your List to contain ArrayLists
- and by implication no other List implementations. Arrays.asList()
returns its own implementation of a List based on the implementation of the array parameter, which may not bean ArrayList. That's your problem.
问题是您指定了要包含的 List ArrayLists
- 并且暗示没有其他 List 实现。Arrays.asList()
根据数组参数的实现返回自己的 List 实现,它可能不是一个 ArrayList。那是你的问题。
More broadly, you have a classic code style problem: You should be referring to abstract interfaces(ie List
), not concrete implementations (ie ArrayList
). Here's how your code should look:
更广泛地说,你有一个经典的代码风格问题:你应该指的是抽象接口(即List
),而不是具体的实现(即ArrayList
)。您的代码应如下所示:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = { "ticker", "grade", "score" };
stuff.add((List<String>) Arrays.asList(titles));
I have tested this code, and it runs without error.
我已经测试了这段代码,它运行没有错误。
回答by Ant Kutschera
Using a debugger, I determined that Array.asList(titles) returns an "Arrays$ArrayList" (ie an inner class of the Arrays class) rather than a java.util.ArrayList.
使用调试器,我确定 Array.asList(titles) 返回“Arrays$ArrayList”(即 Arrays 类的内部类)而不是 java.util.ArrayList。
It's always best to use the interface on the left side of expressions, in this case List rather than the concrete ArrayList. This works fine:
最好使用表达式左侧的接口,在这种情况下是 List 而不是具体的 ArrayList。这工作正常:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((List<String>) Arrays.asList(titles));
回答by AlexR
First, Arrays.asList() should be never casted to ArrayList. Second, since generics were introduced into java programming language casting is still relevant when using legacy, pre-generics APIs.
首先,Arrays.asList() 不应该被强制转换为 ArrayList。其次,由于泛型被引入到 Java 编程语言中,因此在使用遗留的、前泛型 API 时仍然相关。
Third, neveruse concrete classes at the left of assignment operator.
第三,永远不要在赋值运算符的左边使用具体的类。
Bottom line, say
底线,说
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));
and be happy.
而且要快乐。
回答by Srinivasan.S
No need to cast manually. This simple code may help you,
无需手动投射。这个简单的代码可以帮助你,
List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
回答by GFPF
If you want to use your property as ArrayList<'T'> you need only declare there and create a getter.
如果你想使用你的属性作为 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;
}
Initializes the variable and use the method [addAll (Collection collection)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))
初始化变量并使用方法 [addAll (Collection collection)]( http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))