ArrayList<? super IOException> list = new ArrayList<Exception>();
list.add(new FileNotFoundException("this is ok."));
list.add(new IOException("This is ok"));
list.add(new ClassCastException("compile err"));//why compile err?
list.add(new Exception("compile err"));//why compile err?
为什么最后两行不能编译?特别是最后一行。我一直在对这个话题进行相当多的测试,但仍然无法理解逻辑。
感谢。
答案 0 :(得分:8)
ArrayList<? super IOException>
可以是以下任何一种(因为有一张外卡):
ArrayList<IOException>
ArrayList<Exception>
ArrayList<Throwable>
ArrayList<Object>
代码需要处理所有四种可能性。
但如果是ArrayList<IOException>
,则无法输入ClassCastException
或Exception
,因此编译错误。
这是我没有得到的:为什么这个编译------&gt;&gt;&gt; list.add(new FileNotFoundException(“this is ok。”)); &lt;&lt;&lt;&lt; ----我认为FileNotFoundException也低于IOException的界限。但它编译得很好。
不,FileNotFoundException没问题,因为它扩展了IOException,你可以把它放在所有四种类型的列表中。
请注意,由于历史原因,数组不会获得相同的严格类型检查,您可以编译以下内容(然后在运行时获取数组存储异常):
Exception[] a = new IOException[4];
a[0] = new FileNotFoundException("this is ok.");
a[1] = new IOException("This is ok");
a[2] = new ClassCastException("compiles, but boom!");
a[3] = new Exception("compiles, but boom!");
答案 1 :(得分:4)
考虑list
的相同声明,但使用不同的作业:
ArrayList<? super IOException> list = new ArrayList<IOException>();
list
的类型没有变化,但现在添加ClassCastException
或Exception
显然是错误的。
答案 2 :(得分:1)
Exception
是超级类IOException
扩展 Exception
。你可以使用:
List<Exception> list = new ArrayList<Exception>();
list.add(...); // any exception
然后它将编译所有异常类型。
答案 3 :(得分:1)
对我而言,这指的是较低的通配符:<? super IOException>
。上限有界的通配符为<? extends IOException>
。
示例中的通配符似乎仅在将新Object
分配给变量的行中有效。以后访问时,显然不再有效。然后它与ArrayList<IOException>
相同。
所以你对自己的解释显然是错误的。上限和下限意味着它所说的。
答案 4 :(得分:0)
我认为因为异常的最后一个不是从基类IOException
派生的答案 5 :(得分:0)
根据您的ArrayList引用泛型声明,您只能将实际的IOException(由于?super)或将IOException扩展到的对象添加到列表中。
ClassCaseException和Exception不是从IOException派生的,所以它失败了。