铸造数组.asList导致异常:java.util.Arrays$ArrayList不能强制转换为java.util.A



我是Java新手,我试图理解为什么第一个代码段不会导致此异常,但第二个代码段会。因为字符串数组被传递给数组。在这两种情况下,两个片段不都应该产生异常还是不产生异常?

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。

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

List<List<String>> stuff = new ArrayList<List<String>>();

允许添加Arrays.asList(..)方法的结果

如果你这样做,你不会得到任何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包装返回的列表来克服这个问题。

问题是您指定列表包含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));

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

无需手动强制转换。这段简单的代码可以帮助你,

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

使用调试器,我确定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));

如果你想使用你的属性作为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;
    }

初始化变量并使用方法[addAll (Collection Collection)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))

首先,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));

相关内容

  • 没有找到相关文章

最新更新