如何创建List<Class<Exception>>?添加NullPointerException.class失败的原因解析
为什么无法向
List<Class<Exception>>中添加NullPointerException.class? 这个问题其实是Java泛型不变性的典型表现,咱们一步步拆解来理解:
核心原因:泛型的不变特性
虽然NullPointerException是Exception的子类,但它们对应的Class泛型类型之间并没有继承关系——Java的泛型默认是不变的,也就是说:
Class<NullPointerException>既不是Class<Exception>的子类,也不是它的父类- 这两种类型是完全独立的,不能互相兼容
回到你的代码:
List<Class<Exception>> list = new ArrayList();
这个集合的元素类型被严格限定为Class<Exception>,只有完全匹配这个类型的元素才能被添加:
Exception.class的类型正好是Class<Exception>,所以可以正常添加NullPointerException.class的类型是Class<NullPointerException>,和集合要求的类型不匹配,因此IDE会报错,并建议你把集合类型改成List<Class<NullPointerException>>(这样就只能存这个特定异常的Class对象了)
怎么解决这个问题?
如果你想让集合能容纳所有Exception及其子类的Class对象,需要使用**通配符? extends Exception**来实现泛型的协变:
List<Class<? extends Exception>> list = new ArrayList<>(); // 现在这两个操作都能正常执行了 list.add(NullPointerException.class); list.add(Exception.class);
? extends Exception表示“任何继承自Exception的类型的Class对象”,这样就兼容了所有Exception子类的Class类型。
额外补充:为什么泛型要设计成不变的?
这是Java为了保证类型安全做出的设计。举个反例:如果允许把List<Class<NullPointerException>>赋值给List<Class<Exception>>,那之后你可能往这个集合里添加IOException.class(它是Exception的子类),但当你从集合中取出元素并尝试转换为Class<NullPointerException>时,就会出现类型转换错误,破坏了泛型的类型安全保证。
内容的提问来源于stack exchange,提问作者Ilja Tarasovs
相关产品推荐
相关产品推荐

