为什么我可以将Arrays.asList方法与为接口List声明的对象一起使用,但是不能将其声明为ArrayList类的实例时使用?

问题描述

//Splitting a string and passing it to a String Array
String[] b1 = a1.split("");

//The Following throws a compile-time error
ArrayList<String> arrayList1 =  new ArrayList<String>();
arrayList1 = Arrays.asList(b1);

//The following works
List<String> arrayList1 =  new ArrayList<String>();
arrayList1 = Arrays.asList(b1);

我想知道为什么第一种方法会引发错误,而第二种方法却能正常工作? ArrayList实现了List接口,因此应该可以正常工作。

解决方法

ArrayList实现了List接口,因此应该可以正常工作。

不,那不是这样的。如果某个东西返回了接口的实现,则可以将其分配给声明为该接口的对象,而不是相反。

这就是你在做的时候所要做的

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

这完全合法。

但是,如果asList返回的是列表而不是ArrayList(在这里发生的事情)怎么办?您会收到错误消息,因为您要向ArrayList分配一个非ArrayList的东西(并且不是从其派生的)。

还要注意,在第二项测试中,您一进行arrayList1 = Arrays.asList(b1);,就将新的ArrayList分配给arrayList1的事实是完全不相关的,因为接下来要覆盖它行,因此arrayList1只是声明的List

,

Java是静态类型的,当您说变量是String时,就不能为其分配int。您的示例也是如此。当您将arrayList1声明为ArrayList<String>时,就无法为其分配List<String>。因为您无法确定从Arrays.asList()返回的值确实是java.util.ArrayList的实例。

还请注意,存在两个名称为ArrayList的Java类。来自java.util的一个和来自java.util.Arrays的一个。前者是public类中的private,后者是Arrays

,

Arrays.asList(b1)返回java.util.Arrays.ArrayList类型的对象,该对象是Arrays中的嵌套类。

换句话说,您的问题是为什么不能将类型为java.util.Arrays.ArrayList的b1强制转换为类型为java.util.ArrayList的arrayList1:这是两个完全不同的类型,根本不相关。

如果您需要一个java.util.ArrayList,则可以创建一个副本:

ArrayList arrayList1 =新的ArrayList (Arrays.asList(b1));

致谢