下限的通配符

时间:2014-11-29 08:14:27

标签: java generics types

我一直在努力理解Java Generics中下限通配符背后的概念和基本原理。我可以理解上边界通配符背后的推理,以及它在何处以及如何使用。我仍然无法掌握下限的通配符。我有一组遵循以下层次结构的类。 (Automobile是基类。)

Automobile
    - Bus
        - Minibus
        - Doubledecker
        - Electricbus
    - Car
        - Sedan
        - Hatchback
        - Coupe
    - Truck
        - Minivan
        - Pickuptruck
        - Suv
            - Fullsuv
            - Midsuv

现在我正在尝试构建一个(灵活的)列表并向其添加不同类型的对象。

import java.util.ArrayList;
import java.util.List;

public class Garage {

    public static void main(String[] args)
    {
        List<? super Suv> list = null;

        Suv s = new Suv();
        Truck t = new Truck();
        Automobile a = new Automobile();

        list = new ArrayList<Suv>();
        list.add(s); // declared as List<? super Suv> but actually List<Suv>. No compilation error

        list = new ArrayList<Truck>();
        list.add(t); // declared as List<? super Suv> but actually List<Truck>. Compilation error

        list = new ArrayList<Automobile>();
        list.add(a); // declared as List<? super Suv> but actually List<Automobile>. Compilation error
    }
}

我可以将Suv的实例添加到List<? super Suv>。但是当我尝试将TruckAutomobile的实例添加到同一列表时,我收到编译错误。 List<? super Suv>是不是足够灵活,可以接受Suv或其超类的任何实例? TruckAutomobile位于层次结构树中较高的位置。为什么我无法将这些实例添加到列表中?

1 个答案:

答案 0 :(得分:3)

List<? super Suv>应理解为“元素类型为Suv 超级类型的列表。

现在,让我们看看这两行:

list = new ArrayList<Automobile>();
list.add(a); // where a is an Automobile

第一行没问题,因为ArrayList<Automobile>确实是“一个列表,其元素类型是超级类型Suv

但是让我们读出第二行:将一些Automobile添加到一个列表,其元素类型为Suv的超类型。

就编译器从静态类型中所知,

  • list可以引用List<Truck>(因为Truck是超级类型的Suv)和
  • t可以引用Car(因为CarAutomobile

因此编译器会抱怨确保您没有将Car添加到Trucks列表中。


有用的阅读: