我正准备参加Oracle认证专家Java SE 8考试,我在泛型和通配符方面遇到了一些问题。我很清楚,我提交的代码并没有多大意义,也不会以这种方式写在现实生活中。但对我来说这是一个练习。
Action
编译这个怎么编译? ((ArrayList<Exception>)exceptions).add(new Exception());
是包含exceptions
个对象(或子类)的ArrayList
。如何将FileNotFoundException
添加到Exception
,假设只包含ArrayList
子类的元素?如果没有演员表,那么这行不会编译。但即使使用强制转换,异常仍然无法包含FileNotFoundException
的超类。我是对的,还是我误解了什么?
FileNotFoundException
没有编译第1行和第2行之间的区别在于我现在转换为((ArrayList<IOException>)exceptions).add(new Exception());
,而不是IOException
。例外情况太广泛了。当然,要投降到Exception
。这应该是这一行(第5行相同)不编译的原因。正确?
IOException
编译,我不明白为什么。基本上与第1行相同的问题((ArrayList<IOException>)exceptions).add(new IOException());
是IOException
的超类,我怎样才能在这个FileNotFoundException
中加入超类的成员?
ArrayList
编译。与第1行相同的问题。
((ArrayList<Exception>)exceptions).add(new FileNotFoundException());
答案 0 :(得分:1)
这就是为什么你会得到一个不安全的演员&#34;编译器警告 - 因为它不安全。
你所有问题的答案都很糟糕:
答案 1 :(得分:0)
将泛型类型转换为&#34;泛型超类型&#34;编译因为运行时列表只是一个包含对象的列表,这些对象在运行时被检查为类型Exception
(因为它被强制转换为);在运行时期间,ArrayList<FileNotFoundException>
和ArrayList<Exception>
之间没有区别,并且强制转换会覆盖正常的类型检查行为。因此,不像C ++模板,ArrayList<FileNotFoundException>
所持有的引用实际上并不是&#34;无法&#34;引用Exception
个实例,因为在运行时它们只是通用的&#34; Object
&#34;引用(双关语)。
List<? extends Throwable>
表示&#34;某种Throwable
的列表,但我不确定究竟是什么&#34;:因此,使用{{1}初始化引用} object是有效的但在现实生活中并不是非常有用:它意味着你不能在列表中添加任何 ,因为你失去了#34;编译时允许包含的类型。
另一方面,如果您希望能够声明&#34;此列表包含ArrayList<FileNotFoundException>
或其某些父类型&#34;,您可以定义FileNotFoundException
泛型类型。因此,ArrayList<? super FileNotFoundException>
有效且允许您添加ArrayList<? super FileNotFoundException> exceptions = new ArrayList<IOException>();
或FileNotFoundException
,但不允许IOException
。