[英]Java generics with upper bounded wildcards
我正在准备 Oracle Certified Professional Java SE 8 考试,我在泛型和通配符方面遇到了一些问题。 我很清楚我提交的代码没有多大意义,在“现实生活”中不会以这种方式编写,但这对我来说是一个练习。
((ArrayList<Exception>)exceptions).add(new Exception());
编译这个怎么编译? exceptions
是一个包含FileNotFoundException
对象(或子类)的ArrayList
。 如何将Exception
添加到ArrayList
应该只包含FileNotFoundException
子类的元素? 没有演员,该行就无法编译。 但即使使用强制转换,异常仍应无法包含FileNotFoundException
超类。 我是对的还是我误解了什么?
((ArrayList<IOException>)exceptions).add(new Exception());
不编译第 1 行和第 2 行之间的区别在于我现在转换为IOException
,而不是Exception
。 当然,异常太“宽”而无法转换为IOException
。 这应该是这一行(第 5 行相同)无法编译的原因。 对?
((ArrayList<IOException>)exceptions).add(new IOException());
编译,我真的不明白为什么。 与第 1 行的问题基本相同。 IOException
是FileNotFoundException
超类,如何FileNotFoundException
类的成员放入此ArrayList
?
((ArrayList<Exception>)exceptions).add(new FileNotFoundException());
编译。 与第 1 行相同的问题。
package javaapplication;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.io.FileNotFoundException;
public static void main(String[] args) {
List<? extends Throwable> exceptions = new ArrayList<FileNotFoundException>();
((ArrayList<Exception>)exceptions).add(new Exception());//1
((ArrayList<IOException>)exceptions).add(new Exception());//2,does not compile
((ArrayList<IOException>)exceptions).add(new IOException());//3
((ArrayList<Exception>)exceptions).add(new FileNotFoundException());//4
((ArrayList<FileNotFoundException>)exceptions).add(new
Exception());//5,does not compile
}
这就是为什么您会收到“不安全强制转换”编译器警告的原因 - 因为它不安全。
你所有问题的答案都很糟糕:
将泛型类型转换为“泛型超类型”是可以编译的,因为运行时列表只是一个包含对象的列表,这些对象在运行时被检查为Exception
类型(因为它被转换为Exception
类型); 在运行时, ArrayList<FileNotFoundException>
和ArrayList<Exception>
之间没有区别,并且ArrayList<Exception>
覆盖了正常的类型检查行为。 因此,与例如 C++ 模板不同,由ArrayList<FileNotFoundException>
持有的引用实际上并不是“无法”引用Exception
实例,因为在运行时它们只是通用的“ Object
”引用(双关语)。
List<? extends Throwable>
List<? extends Throwable>
表示“某种Throwable
的列表,但我不太确定到底是什么”:因此,使用ArrayList<FileNotFoundException>
对象初始化引用是有效的,但在现实生活中并不是非常有用:这意味着您可以不要向列表中添加任何内容,因为您“丢失”了编译时间后允许包含的类型。
另一方面,如果您希望能够声明“此列表包含FileNotFoundException
或其某些父类型”,您可以定义一个ArrayList<? super FileNotFoundException>
ArrayList<? super FileNotFoundException>
泛型类型。 因此, ArrayList<? super FileNotFoundException> exceptions = new ArrayList<IOException>();
ArrayList<? super FileNotFoundException> exceptions = new ArrayList<IOException>();
是有效的,并且允许您添加FileNotFoundException
或IOException
但不是例如Exception
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.