Java 具有下限通配符的编译错误

Java 具有下限通配符的编译错误,java,generics,java-8,Java,Generics,Java 8,考虑以下示例: public static void main(String... args) { List<? super IOException> exceptions = new ArrayList<Exception>(); exceptions.add(new Exception()); // Compile Error exceptions.add(new IOException()); exceptions.add

考虑以下示例:

public static void main(String... args) {
    List<? super IOException> exceptions = new ArrayList<Exception>();
    exceptions.add(new Exception());       // Compile Error
    exceptions.add(new IOException());
    exceptions.add(new FileNotFoundException());
}
publicstaticvoidmain(字符串…参数){
当你说

下界通配符接受通配符中给定类的所有超类

它指的是参数化类型,而不是可能传递给方法的对象的类型。您可以将
列表
分配给该变量,甚至可以将
列表
分配给该变量

编译器不能假定
异常
可以保存
异常
。实际类型参数可能与下限一样具体,在本例中为
IOException
。将
列表
分配给
异常
,在这种情况下,您应该无法添加
异常因此,编译器不允许该语句

如果要添加
异常
并保留下限,请将下限更改为:

List<? super Exception> exceptions = new ArrayList<Exception>();

List您的代码未编译的原因是以下内容是合法的:

List<? super IOException> exceptions = new ArrayList<IOException>();
甚至:

// Also no compiler errors
List<Exception> exceptions = new ArrayList<>();
exceptions.add(new Exception());
exceptions.add(new IOException());
exceptions.add(new FileNotFoundException());
//也没有编译器错误
列表异常=新建ArrayList();
添加(新的异常());
添加(新IOException());
添加(新文件notfoundexception());

你建议的列表声明方式和我在问题中提到的是一样的。恐怕我遗漏了什么吗?那是指类型参数……我认为参数化类型会更准确。也就是说,用下界
T
参数化的类型是用超类型
T参数化的同一类型的超类型
。如果它是一个
ArrayList怎么办?
?你是对的。“IOException”不能保存“Exception”。但是为什么“Exception”不能保存“Exception”?编译器只关心列表声明为什么类型,在本例中是
列表
// No compiler errors
List<? super Exception> exceptions = new ArrayList<Exception>();
exceptions.add(new Exception());
exceptions.add(new IOException());
exceptions.add(new FileNotFoundException());
// Also no compiler errors
List<Exception> exceptions = new ArrayList<>();
exceptions.add(new Exception());
exceptions.add(new IOException());
exceptions.add(new FileNotFoundException());