英文:
Why I am able to use Arrays.asList method with an object declared for interface, List, but not when it is declared as an instance of class ArrayList?
问题
第一种方法会引发编译时错误,而第二种方法可以正常工作,原因是:
在第一种方法中,您首先创建了一个ArrayList
对象,然后尝试将一个String
数组赋值给它。这是一个问题,因为Arrays.asList(b1)
返回的是一个List
,而不是ArrayList
。虽然ArrayList
实现了List
接口,但在这种情况下,编译器无法隐式地将List
转换为ArrayList
。因此,这会导致编译时错误。
而在第二种方法中,您直接创建了一个List<String>
对象,并将Arrays.asList(b1)
的结果赋值给它。这样做是正确的,因为List
是一个更抽象的接口,可以容纳不同类型的List
实现,包括ArrayList
。这种方式可以正常工作,因为您没有尝试将一个更具体的类型(ArrayList
)分配给一个更一般的类型(List
),所以不会引发编译错误。
英文:
//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);
I want to know why the first approach throws error whereas the second one works well? ArrayList
implements List
interface, so it should work well.
答案1
得分: 4
ArrayList
实现了List
接口,所以它应该能够正常工作。
不对,事情并不是这样的。如果某个东西返回了一个接口的实现,你可以将它赋值给一个声明为该接口的对象,而不是反过来赋值。
当你执行以下操作时:
List<String> arrayList1 = new ArrayList<String>();
这是完全合法的。
但是,如果asList
返回的是一个List
而不是ArrayList
(这就是这里发生的情况),会出现错误,因为你正在将一个不是ArrayList
(并且没有从它继承)的东西赋值给一个ArrayList
。
还要注意,在第二个测试中一旦执行了arrayList1 = Arrays.asList(b1);
,将新的ArrayList
赋值给arrayList1
的事实就变得完全无关紧要了,因为你接下来又覆盖了它,所以arrayList1
只是一个声明为List
的对象。
英文:
> ArrayList
implements List
interface, so it should work well.
Nope, that's not how that works. If something returns an implementation of an interface you can assign it to an object declared as that interface, not the other way around.
That's what you're doing when you're doing
List<String> arrayList1 = new ArrayList<String>();
Which is totally legal.
But what if asList
returns something that is a List but not an ArrayList (which is what's happening here)? You get an error, because you're assigning something that is not an ArrayList
(and does not descend from it) to an ArrayList
.
Also notice that as soon as you do arrayList1 = Arrays.asList(b1);
in the second test, the fact that you assigned a new ArrayList
to arrayList1
is totally irrelevant, as you're overwriting it next line, so arrayList1
is just a List
, as declared.
答案2
得分: 2
Java是静态类型的,当你声明一个变量是String
时,你不能把一个int
赋值给它。对你的示例也是一样的。当你将arrayList1
声明为ArrayList<String>
时,你不能将一个List<String>
赋值给它。因为你不能确定从Arrays.asList()
返回的值是否真的是java.util.ArrayList
的实例。
还要注意,存在两个名为ArrayList
的Java类。一个来自java.util
,另一个来自java.util.Arrays
。前者是public
的,而后者是Arrays
类内部的private
。
英文:
Java is statically typed, when you say a variable is a String
then you can't assign an int
to it. The same goes for your example. When you declare arrayList1
as a an ArrayList<String>
then you can't assign a List<String>
to it. Because you can't be sure that the value returned from Arrays.asList()
is really an instance of java.util.ArrayList
.
Also be careful there exists two java classes with the name ArrayList
. The one from java.util
and the one from java.util.Arrays
. The former is public
and the latter is private
inside the Arrays
class
答案3
得分: 0
Arrays.asList(b1)返回一个类型为java.util.Arrays.ArrayList的对象,它是Arrays内部的一个嵌套类。
换句话说,你的问题是为什么类型为java.util.Arrays.ArrayList的b1不能强制转换为类型为java.util.ArrayList的arrayList1:它们是完全不相关的两种不同类型。
如果你需要一个java.util.ArrayList,你可以创建一个副本:
ArrayList<String> arrayList1 = new ArrayList<>(Arrays.asList(b1));
致敬
英文:
Arrays.asList(b1) returns an object of type java.util.Arrays.ArrayList which is a nested class within Arrays.
In other words, your question is why b1 of type java.util.Arrays.ArrayList cannot be casted into arrayList1 which is of type java.util.ArrayList : these are two completely different types not related at all.
If you need a java.util.ArrayList, you can just create a copy:
ArrayList<String> arrayList1 = new ArrayList<>(Arrays.asList(b1));
Regards
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论