为什么第一行有效,第二行不行?
Collection<Class<? extends Throwable>> exs =
new ArrayList<Class<? extends Throwable>>() {{ add(MyOwnException.class); }};
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
它是错误的原因是 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>
Generics are very tricky.
In this case Arrays.asList
will return a List<Class<MyOwnException>>
, which is not the same than List<Class<? extends Throwable>>
.
Their behavior will differ since the type List<Class<? extends Throwable>>
would allow you to add objects that extend Throwable but List<Class<MyOwnException>>
only accept objects of type MyOwnException.
Arrays.asList(MyOwnException.class)
推断有 type ,由于类型参数不同List<Class<MyOwnException>>
,所以不兼容。List<Class<? extends Throwable>>
如果您将通配符放在第一级,它应该可以工作:
Collection<? extends Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
第一行有效,因为分配右侧元素的类型(的ArrayList
)是Class<? extends Throwable>
允许添加任何类型的Class<? extends Throwable>
对象,包括你的MyOwnException
. 您还可以在第一行添加Collection
anException.class
或 aNullPointerException.class
等。
但是第二行要严格得多:你有一个Collection<Class<? extends Throwable>>
可能包含 a Class<Exception>
、 aClass<NullPointerException>
等的 a ,并且你想放置一个Collection<Class<MyOwnException>>
不允许Class<Exception>
等的 a 。
如果第二个示例可以工作,它将允许这样的代码:
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
exs.add(IOException.class);
看到问题了吗?Arrays.asList()
将返回 a List<Class<MyOwnException>>
,然后您将尝试将 aClass<IOException>
插入其中。这显然是类型不匹配。