簡體   English   中英

在另一個通用接口內使用通用接口

[英]Using a generic interface inside another generic interface

我有一個類型為List<List<Integer>>的變量e4 ,我想用一個new ArrayList<ArrayList<Integer>>()進行初始化。 我希望這將以與為List<Integer> -type變量分配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

原因是,即使ArrayList<Integer>List<Integer>List<ArrayList<Integer>>也不是List<List<Integer>> 這里的推理與List<Dog>不是List<Animal>的事實相同,即使DogAnimal 類比是ArrayList<Integer>List<Integer>就像DogAnimal

以下是替代方法:

1)您的“ e5”,它與泛型類型完全匹配。

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>>();

java的工作方式

List<List<Integer>> list = new ArrayList<ArrayList<Integer>>

將不起作用,因為內部ArrayList與List的類型不匹配。 它正在尋找一個列表。

您需要以下內容

List<? extends List<Integer>> list = new ArrayList<ArrayList<Integer>>();

原因是,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>>();
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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM