为什么第一行有效,但第二行没有?
Collection<Class<? extends Throwable>> exs =
new ArrayList<Class<? extends Throwable>>() {{ add(MyOwnException.class); }};
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
答案 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
延伸A
,List<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>
。您还可以添加到第一行MyOwnException
和Collection
或Exception.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>
。这显然是一种类型不匹配。