Java 下界通配符

Java 下界通配符,java,generics,types,Java,Generics,Types,我一直在试图理解Java泛型中下界通配符背后的概念和原理。我可以理解上界通配符是只读的背后的原因,以及在哪里和如何使用它。我仍然无法掌握下界通配符。我有一组遵循以下层次结构的类。(Automobile是基类。) 现在我正在尝试构建一个(灵活的)列表,并向其中添加不同类型的对象 import java.util.ArrayList; import java.util.List; public class Garage { public static void main(String[]

我一直在试图理解Java泛型中下界通配符背后的概念和原理。我可以理解上界通配符是只读的背后的原因,以及在哪里和如何使用它。我仍然无法掌握下界通配符。我有一组遵循以下层次结构的类。(
Automobile
是基类。)

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

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
    }
}
import java.util.ArrayList;
导入java.util.List;
公共级车库{
公共静态void main(字符串[]args)
{

List
List这是一个重要的区别:编译器只知道
List
的声明通配符类型,而不知道实际的实例化类型。当该行运行时,它无法执行必要的分析以找到真正的类型,部分原因是它不实用,但也因为JLS不允许它。@aioobe如果我想这样做的话将卡车或汽车的实例添加到列表中,我是否需要为它们声明专门声明的列表?我回答底部链接中的列表:“如果您从参数化容器中获取了一些内容,请使用extends。[…]如果您将对象放入参数化容器中,请使用super。”如果您的
loadGarage
方法应将
汽车
放在提供的列表中,您应让该方法接受任何可以存储
汽车
的列表,即
列表
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
    }
}
list = new ArrayList<Automobile>();
list.add(a); // where a is an Automobile