Java泛型:创建扩展Throwable的类对象集合

时间:2012-09-19 23:18:47

标签: java generics

为什么第一行有效,但第二行没有?

Collection<Class<? extends Throwable>> exs =
    new ArrayList<Class<? extends Throwable>>() {{ add(MyOwnException.class); }};
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);

5 个答案:

答案 0 :(得分:6)

这是一个错误的原因是java推断出错误的类型,但你可以通过在对类型化方法Arrays.asList()的调用中指定类型来使其编译,而无需强制转换

Collection<Class<? extends Throwable>> exs 
    = Arrays.<Class<? extends Throwable>>asList(Exception.class); // compiles

如果不指定类型,java会将集合的元素类型推断为Class<Exception>可分配给Collection<Class<? extends Throwable>>

请记住,如果B延伸AList<B> 延长List<A>

答案 1 :(得分:3)

泛型非常棘手。

在这种情况下,Arrays.asList将返回List<Class<MyOwnException>>,这与List<Class<? extends Throwable>>不同。

它们的行为会有所不同,因为类型List<Class<? extends Throwable>>允许您添加扩展Throwable的对象,但List<Class<MyOwnException>>只接受MyOwnException类型的对象。

答案 2 :(得分:1)

第一行有效,因为(ArrayList)分配的右侧元素的类型为Class<? extends Throwable>,允许添加任何类型{ {1}}对象,包括您的Class<? extends Throwable>。您还可以添加到第一行MyOwnExceptionCollectionException.class等。

但第二行更加严格:你有一个NullPointerException.class可能包含Collection<Class<? extends Throwable>>Class<Exception>等等,你想要放置一个{{1} }不允许Class<NullPointerException>等等。

答案 3 :(得分:1)

Arrays.asList(MyOwnException.class)被推断为类型List<Class<MyOwnException>>,与List<Class<? extends Throwable>>不兼容,因为类型参数不同。

如果你在第一级放置一个通配符,它​​应该可以工作:

Collection<? extends Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);

答案 4 :(得分:0)

如果第二个例子有效,它将允许这样的代码:

Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
exs.add(IOException.class);

看到问题? Arrays.asList()会返回List<Class<MyOwnException>>,然后您会尝试在其中插入Class<IOException>。这显然是一种类型不匹配。