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新手,我正在尝试理解为什么第一个代码段不会导致这个异常,但是第二个代码段会。因为字符串数组被传递到数组中。在这两种情况下,两个片段都不应该产生异常或不产生异常吗?
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。
7 个解决方案
#1
31
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),第一个代码段给出与第二个代码段相同的异常。原因是array . aslist(..)方法只返回一个列表,而不一定是一个ArrayList。因为您不知道方法返回的列表的类型(或实现),您的cast到ArrayList
List<List<String>> stuff = new ArrayList<List<String>>();
which will allow to add whatever comes out of the Arrays.asList(..)
method.
它将允许添加来自array . aslist(..)方法的任何内容。
#2
10
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. ArrayList不同。因此,例外。我们通过使用java.util.ArrayList包装返回的列表来克服这个问题。
#3
10
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 be an ArrayList. That's your problem.
问题是,您指定您的列表包含arraylist——并且暗示没有其他的List实现。aslist()根据数组参数的实现返回自己的列表实现,数组参数可能不是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:
更广泛地说,您有一个典型的代码样式问题:您应该引用抽象接口(ie List),而不是具体实现(ie 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.
我已经测试了这段代码,它运行无误。
#4
8
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)));
#5
1
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(title)返回“array $ArrayList”(即数组类的内部类),而不是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:
在本例列表中,最好使用表达式左边的接口,而不是具体的ArrayList。这工作正常:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((List<String>) Arrays.asList(titles));
#6
1
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)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))
#7
0
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.
首先,array . aslist()不应该被强制到ArrayList。其次,由于泛型被引入到java编程语言中,在使用遗留的、前泛型api时,泛型仍然是相关的。
Third, never use 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.
和快乐。
#1
31
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),第一个代码段给出与第二个代码段相同的异常。原因是array . aslist(..)方法只返回一个列表,而不一定是一个ArrayList。因为您不知道方法返回的列表的类型(或实现),您的cast到ArrayList
List<List<String>> stuff = new ArrayList<List<String>>();
which will allow to add whatever comes out of the Arrays.asList(..)
method.
它将允许添加来自array . aslist(..)方法的任何内容。
#2
10
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. ArrayList不同。因此,例外。我们通过使用java.util.ArrayList包装返回的列表来克服这个问题。
#3
10
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 be an ArrayList. That's your problem.
问题是,您指定您的列表包含arraylist——并且暗示没有其他的List实现。aslist()根据数组参数的实现返回自己的列表实现,数组参数可能不是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:
更广泛地说,您有一个典型的代码样式问题:您应该引用抽象接口(ie List),而不是具体实现(ie 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.
我已经测试了这段代码,它运行无误。
#4
8
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)));
#5
1
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(title)返回“array $ArrayList”(即数组类的内部类),而不是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:
在本例列表中,最好使用表达式左边的接口,而不是具体的ArrayList。这工作正常:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((List<String>) Arrays.asList(titles));
#6
1
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)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))
#7
0
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.
首先,array . aslist()不应该被强制到ArrayList。其次,由于泛型被引入到java编程语言中,在使用遗留的、前泛型api时,泛型仍然是相关的。
Third, never use 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.
和快乐。