java中的有界通配符下界泛型即使在传递超类时也不会编译
List<? super IOException>
表示列表可以包含IOException
对象或IOException
类的super
对象。那么为什么下面的第2行不编译呢
同样在第3行FileNotFoundException
不是IOException
的super
类。那为什么要编译呢
List<? super IOException> myList = new ArrayList<Exception>();
myList.add(new Exception()); //Line 2 This line do not compile
myList.add(new FileNotFoundException()); //Line 3 This compiles
# 1 楼答案
这是:
编译是因为
FileNotFoundException
是一个IOException
,就像它是一个Exception
,所以它满足myList
的界限这是:
不编译,因为编译器不知道列表的确切类型(它不检查分配给变量的是什么,它只查看它声明的类型),所以它不知道分配给它的列表是否有一个与超级类型
IOException
匹配的类型,而不是Exception
如果在
Exception
和IOException
之间的层次结构中有一个中间类,就会发生这种情况。如果列表实际具有该类型,Exception
可能与分配给myList
的实际列表的界限不匹配编译器不会检查完整的类层次结构,也不会检查分配了什么。它只做基本检查,总是避免运行时错误
在“逻辑上”没有会导致错误的代码路径,但编译仍然失败的情况下,更普遍的情况也是如此
# 2 楼答案
myList引用的列表可以是
List<IOException>
或List<Exception>
或List<Object>
。第2行没有编译,因为我们可以有一个List<IOException>
和 异常对象不适合放在那里File-NotFoundException
也可以添加到这三种类型中的任何一种。这很棘手,因为FileNotFoundException
是IOException
的一个子类,关键字是super
编译器查看引用类型:
List<? super IOException>
所有可能的类型,以便:然后它穿过
myList.add(new Exception());
行,发现它无法编译,因为它无法放入List<IOException>
# 3 楼答案
通配符下限为类型参数指定下限,而不是为
List
的可接受类型指定下限。类型参数可以像IOException
一样具体,但也可以像我们所能得到的那样一般:Object
添加
Exception
时,项的类型作为项太一般,因为类型参数可能太具体,可能是IOException
。编译器不允许您向可能只需要IOException
秒的内容添加Exception
,因此它会生成错误这不会发生在} 在所有情况下都是合法的,它是
FileNotFoundException
上,因为无论类型参数有多具体,它都不会比IOException
(下限)更具体,因此^{IOException
的子类,因此编译器允许它