7

为什么第一行有效,第二行不行?

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

5 回答 5

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>

于 2012-09-20T01:55:23.137 回答
3

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.

于 2012-09-19T23:28:14.977 回答
1

Arrays.asList(MyOwnException.class)推断有 type ,由于类型参数不同List<Class<MyOwnException>>,所以不兼容。List<Class<? extends Throwable>>

如果您将通配符放在第一级,它应该可以工作:

Collection<? extends Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class);
于 2012-09-20T06:59:33.063 回答
1

第一行有效,因为分配右侧元素的类型(的ArrayList)是Class<? extends Throwable>允许添加任何类型的Class<? extends Throwable>对象,包括你的MyOwnException. 您还可以在第一行添加CollectionanException.class或 aNullPointerException.class等。

但是第二行要严格得多:你有一个Collection<Class<? extends Throwable>>可能包含 a Class<Exception>、 aClass<NullPointerException>等的 a ,并且你想放置一个Collection<Class<MyOwnException>>不允许Class<Exception>等的 a 。

于 2012-09-20T00:05:32.933 回答
0

如果第二个示例可以工作,它将允许这样的代码:

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

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

于 2012-09-19T23:46:00.487 回答