简体   繁体   English

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

[英]Java generics: creating collections of class objects extending Throwable

Why does the first line work, but the second one doesn't? 为什么第一行有效,但第二行没有?

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

The reason it's an error is that java is inferring the wrong type, but you can make it compile, without casting , by specifying the type in the call to the typed method Arrays.asList() : 它是一个错误的原因是java推断出错误的类型,但你可以通过在类型化方法Arrays.asList()的调用中指定类型来进行编译而不进行转换

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

Without specifying the type, java infers the element type of the collection to be Class<Exception> , which is not assignable to Collection<Class<? extends Throwable>> 如果不指定类型,java会将集合的元素类型推断为Class<Exception>而不能将其分配给Collection<Class<? extends Throwable>> Collection<Class<? extends Throwable>> . Collection<Class<? extends Throwable>>

Remember with generics that if B extends A , List<B> does not extend List<A> . 记住泛型,如果B延伸AList<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>> 在这种情况下, Arrays.asList将返回一个List<Class<MyOwnException>> ,它与List<Class<? extends Throwable>> List<Class<? extends Throwable>> . List<Class<? extends Throwable>>

Their behavior will differ since the type List<Class<? extends Throwable>> 他们的行为会因List<Class<? extends Throwable>>而有所不同 List<Class<? extends Throwable>> would allow you to add objects that extend Throwable but List<Class<MyOwnException>> only accept objects of type MyOwnException. List<Class<? extends Throwable>>允许你添加扩展Throwable的对象,但List<Class<MyOwnException>>只接受MyOwnException类型的对象。

The first line works because the type of the element of the right side of the assignement (of the ArrayList ) is Class<? extends Throwable> 第一行是有效的,因为Assignement( ArrayList右侧元素的类型是Class<? extends Throwable> Class<? extends Throwable> that allows to add any kind of Class<? extends Throwable> Class<? extends Throwable>允许添加任何Class<? extends Throwable> Class<? extends Throwable> object, including your MyOwnException . Class<? extends Throwable> object,包括MyOwnException You could also add to the first line Collection an Exception.class or a NullPointerException.class , etc. 您还可以在第一行Collection添加Exception.classNullPointerException.class等。

But the second line is much stricter: you have a Collection<Class<? extends Throwable>> 但第二行更加严格:你有一个Collection<Class<? extends Throwable>> Collection<Class<? extends Throwable>> that might contain a Class<Exception> , a Class<NullPointerException> , etc. and you want to put in place a Collection<Class<MyOwnException>> that don't allows for Class<Exception> , etc. Collection<Class<? extends Throwable>>可能包含Class<Exception>Class<NullPointerException>等,并且您希望放置一个Collection<Class<MyOwnException>> ,它不允许Class<Exception>等。

Arrays.asList(MyOwnException.class) is inferred to have type List<Class<MyOwnException>> , which is not compatible with List<Class<? extends Throwable>> 推断Arrays.asList(MyOwnException.class)具有类型List<Class<MyOwnException>> ,它与List<Class<? extends Throwable>>不兼容List<Class<? extends Throwable>> List<Class<? extends Throwable>> since the type parameters are different. List<Class<? extends Throwable>>因为类型参数不同。

If you put a wildcard at the first-level, it should work: 如果你在第一级放一个通配符,它​​应该工作:

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

If the second example were to work, it would allow for code like this: 如果第二个例子工作,它将允许这样的代码:

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

See the problem? 看到问题? Arrays.asList() would return a List<Class<MyOwnException>> , and then you'd be trying to insert a Class<IOException> into that. Arrays.asList()将返回List<Class<MyOwnException>> ,然后您将尝试将Class<IOException>插入其中。 That's obviously a type mismatch. 这显然是一种类型不匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM