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

转换Arrays.asList导致异常:java.util.Arrays$ArrayList无法转换为java.util.ArrayList,java,arrays,casting,multidimensional-array,arraylist,Java,Arrays,Casting,Multidimensional Array,Arraylist,我是Java新手,正在尝试理解为什么第一个代码段不会导致此异常,而第二个代码段会导致此异常。由于字符串数组在这两种情况下都被传递到Arrays.asList中,这两个代码段不都应该生成异常还是不生成异常 Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList 第一个代码段(不会导致异常): ArrayList

我是Java新手,正在尝试理解为什么第一个代码段不会导致此异常,而第二个代码段会导致此异常。由于字符串数组在这两种情况下都被传递到Arrays.asList中,这两个代码段不都应该生成异常还是不生成异常

Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
第一个代码段(不会导致异常):

ArrayList stuff=new ArrayList();
String line=“a,b,cdef,g”;
字符串delim=“,”;
字符串[]个数=行分割(delim);
添加((ArrayList)Arrays.asList(片断));
第二个代码段(导致上述异常):

ArrayList stuff=new ArrayList();
String[]titles={“ticker”、“grade”、“score”};
添加((ArrayList)Arrays.asList(titles));

如果相关的话,我正在Eclipse Helios中使用JavaSE 1.6。

如果这样做,您将不会得到任何CCE:

ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(new ArrayList<String>(Arrays.asList(titles)));
ArrayList stuff=new ArrayList();
String[]titles={“ticker”、“grade”、“score”};
添加(新的ArrayList(Arrays.asList(titles));

正如错误明确指出的那样,类
java.util.ArrayList
与嵌套的静态类
java.util.ArrayList
不同。因此有例外。我们通过使用
java.util.ArrayList
包装返回的列表来解决这个问题。问题是您指定列表包含
ArrayList
,并且暗示没有其他列表实现
Arrays.asList()
根据数组参数的实现返回自己的列表实现,该参数可能不是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[]titles={“ticker”、“grade”、“score”};
添加((列表)数组.asList(标题));
我已经测试了这段代码,它运行时没有错误。

对于我(使用Java 1.6.0_26),第一个代码段给出了与第二个代码段相同的异常。原因是该方法只返回
列表
,不一定返回
数组列表
。因为您不知道该方法返回的
List
的类型(或实现),所以您对
ArrayList
的强制转换是不安全的。结果是,它可能按照预期工作,也可能不按照预期工作。从编码风格的角度来看,一个很好的解决方法是将
内容
声明更改为:

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

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

使用调试器,我确定Array.asList(titles)返回“Arrays$arraryList”(即Arrays类的内部类)而不是java.util.ArrayList

在本例中,最好使用表达式左侧的接口,而不是具体的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[]titles={“ticker”、“grade”、“score”};
添加((列表)数组.asList(标题));
首先,决不能将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));
List stuff=new ArrayList();
String line=“a,b,cdef,g”;
字符串delim=“,”;
字符串[]个数=行分割(delim);
stuff.add(Arrays.asList(片断));
List stuff=new ArrayList();
String[]titles={“ticker”、“grade”、“score”};
添加(数组.asList(标题));

而且要快乐。

无需手动施法。这个简单的代码可能会帮助您

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

如果要将属性用作ArrayList,只需在其中声明并创建一个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;
    }
私有静态数组列表bandsArrayList;
公共阵列列表getBandsArrayList(){
if(bandsArrayList==null){
bandsArrayList=newarraylist();
字符串[]带={“金属”、“铁娘子”、“涅盘”};
addAll(Arrays.asList(bands));
}
返回带列表;
}

初始化变量并使用方法[addAll(Collection)]()

我在IBM JDK上,对我来说,即使是你的第一个代码片段也会出现同样的错误!谢谢你的回答。每个答案都提供了有用的信息,帮助我更好地理解Java,并提醒我使用良好的编码风格。谢谢,@adarshr。我发现了这一点,但忘了在我的问题中贴出来。我仍然对异常的原因感到好奇。我认为这个答案更相关,因为Arrays$ArrayList代表Arrays类中定义的内部类ArrayList。如何确定使用new ArrayList而不是new List或new List?@DannyTree Java
new
关键字创建一个类的新实例。为此,类必须是“具体的”(如“非抽象的”)。这基本上意味着它可能没有“松散的结尾”,所有方法都必须有实现。当你说
新建列表
时,你没有指定要实例化哪种类型的
列表
,因此这不起作用。这个答案帮助我理解了其他答案关于编码到接口而不是实现以及我的转换是如何不安全的。很好的解释。本页下面是另一个简单的解决方案。如果无法将ArrayList更改为List,这是一个很好的解决方案。
List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
    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;
    }