Javagenerics与多个类的通配符

我想要一个Class对象,但是我想强制它所代表的任何类来扩展类A并实现接口B.

我可以:

Class<? extends ClassA> 

要么:

 Class<? extends InterfaceB> 

但我不能这样做。 有没有办法做到这一点?

其实,你可以做你想做的。 如果你想提供多个接口或一个类加接口,你必须让你的通配符看起来像这样:

 <T extends ClassA & InterfaceB> 

请参阅sun.com上的“ generics教程” ,特别是页面底部的“ 有界types参数”部分。 如果您愿意,您可以实际列出多个接口,使用& InterfaceName作为您需要的每个& InterfaceName

这可以任意复杂。 为了演示,请参阅Collections#max的JavaDoc声明,其中(包装到两行)是:

 public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 

为什么这么复杂? 正如Javagenerics常见问题解答中所述: 保持二进制兼容性 。

它看起来像这不适用于variables声明,但它在将一个generics边界放在类上时工作。 因此,要做你想做的事情,你可能需要跳过几圈。 但是你可以做到。 你可以做这样的事情,把一个通用的边界放在你的课堂上,然后:

 class classB { } interface interfaceC { } public class MyClass<T extends classB & interfaceC> { Class<T> variable; } 

得到你想要的限制的variable 。 有关更多信息和示例,请参阅Java 5.0中的generics的第3页。 请注意,在<T extends B & C> ,类名必须先出现,然后再接口。 当然,你只能列出一个class级。

你不能用“匿名”types参数(即使用?通配符)来完成,但是你可以用“命名”types参数来完成。 只需在方法或类级别声明types参数。

 import java.util.List; interface A{} interface B{} public class Test<E extends B & A, T extends List<E>> { T t; }