在另一个通用接口内使用通用接口

时间:2014-03-19 18:32:36

标签: java generics interface nested

我有e4类型的变量List<List<Integer>>,我想用new ArrayList<ArrayList<Integer>>()进行初始化。我希望这可以工作,类似于如何分配List<Integer> - 类型变量new ArrayList<Integer>()。相反,存在编译错误;这背后的原因是什么,是否有必要使用e3e5等语句?

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

4 个答案:

答案 0 :(得分:4)

原因是List<ArrayList<Integer>>不是List<List<Integer>>,即使ArrayList<Integer>List<Integer>。这里的推理与List<Dog>不是List<Animal>的事实相同,即使DogAnimal。类比是ArrayList<Integer>List<Integer>DogAnimal

以下是替代方案:

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>的子类型,即使IntegerNumber的子类型。

将该概念用于嵌套泛型:

// 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.