我有e4
类型的变量List<List<Integer>>
,我想用new ArrayList<ArrayList<Integer>>()
进行初始化。我希望这可以工作,类似于如何分配List<Integer>
- 类型变量new ArrayList<Integer>()
。相反,存在编译错误;这背后的原因是什么,是否有必要使用e3
或e5
等语句?
import java.util.List;
import java.util.ArrayList;
public class Example {
public static void main(String[] args) {
// e1-3 compile as expected
ArrayList<Integer> e1 = new ArrayList<Integer>();
List<Integer> e2 = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> e3 = new ArrayList<ArrayList<Integer>>();
// e4 does not compile
List<List<Integer>> e4 = new ArrayList<ArrayList<Integer>>();
// e5 does compile
List<ArrayList<Integer>> e5 = new ArrayList<ArrayList<Integer>>();
}
}
在尝试编译上面的内容时,我收到错误消息:
/home/james/Example.java:12: error: incompatible types
List<List<Integer>> e4 = new ArrayList<ArrayList<Integer>>();
^
required: List<List<Integer>>
found: ArrayList<ArrayList<Integer>>
1 error
答案 0 :(得分:4)
原因是List<ArrayList<Integer>>
不是List<List<Integer>>
,即使ArrayList<Integer>
是List<Integer>
。这里的推理与List<Dog>
不是List<Animal>
的事实相同,即使Dog
是Animal
。类比是ArrayList<Integer>
到List<Integer>
,Dog
到Animal
。
以下是替代方案:
1)你的&#34; e5&#34;,它与通用类型完全匹配。
List<ArrayList<Integer>> e5 = new ArrayList<ArrayList<Integer>>();
或
List<List<Integer>> e5 = new ArrayList<List<Integer>>();
2)使用通配符:
List<? extends List<Integer>> e6 = new ArrayList<ArrayList<Integer>>();
答案 1 :(得分:0)
java的工作方式
List<List<Integer>> list = new ArrayList<ArrayList<Integer>>
将无法工作,因为内部ArrayList与List的类型不匹配。它正在寻找一个List。
您需要以下
List<? extends List<Integer>> list = new ArrayList<ArrayList<Integer>>();
答案 2 :(得分:0)
原因是,Java中的泛型是不变的。让我们先看一个非常简单的例子:
// This doesn't compile
List<Number> list = new ArrayList<Integer>();
上述作业无法编译,因为ArrayList<Integer>
不是List<Number>
的子类型,即使Integer
是Number
的子类型。
将该概念用于嵌套泛型:
// This also shouldn't compile
List<List<Integer>> list = new ArrayList<ArrayList<Integer>>();
虽然ArrayList<Integer>
是List<Integer>
的子类型,但ArrayList<ArrayList<Integer>>
不是List<List<Integer>>
的子类型。所以它没有编译。
要进行编译,可以在那里使用有界通配符:
// This would work now.
List<? extends List<Integer>> list = new ArrayList<ArrayList<Integer>>();
答案 3 :(得分:0)
Whenever you are specifying ;
List<List<Integer>> e4 = new ArrayList<ArrayList<Intger>>();
This stands out to be wrong because when you are creating the ArrayList (Implementation of the List) e4 you are specifying that it can contain List (all kinds of implementation of lists) of Integer but while instantiating it you are strictly specifying it as ArrayList of Integer which is contradicting with your declaration.
Moreover Polymorphism only applies to the base type (Base type means the collection class itself.)
Your example can be correlated with another example :
List<Number> l1= new ArrayList<Integer>(); /*This will never compile though Integer is a subclass of Number as we are not only changing the base type but also the generic type which is wrong.*/
But this will definitely compile
List<Number> l2 =new ArrayList<Number>(); //Changed only the base type.
For better understanding read Sun Certified Programmer for Java 6 by Kathy Sierra and Bert Bates.