铸造数组。asList造成例外:java.util。数组$ArrayList不能被转换为java.util.ArrayList

时间:2021-01-19 19:31:41

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.

和快乐。