本文翻译自:Java Generics Wildcarding With Multiple Classes
I want to have a Class object, but I want to force whatever class it represents to extend class A and implement interface B. 我想要一个Class对象,但我想强制它所代表的任何类来扩展A类并实现接口B.
I can do: 我可以:
Class<? extends ClassA>
Or: 要么:
Class<? extends InterfaceB>
but I can't do both. 但我不能两者兼顾。 Is there a way to do this? 有没有办法做到这一点?
#1楼
参考:https://stackoom.com/question/380K/具有多个类的Java泛型通配符
#2楼
You can't do it with "anonymous" type parameters (ie, wildcards that use ?
), but you can do it with "named" type parameters. 您不能使用“匿名”类型参数(即使用?
通配符)来执行此操作,但您可以使用“命名”类型参数执行此操作。 Simply declare the type parameter at method or class level. 只需在方法或类级别声明类型参数即可。
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}
#3楼
A type parameter can have multiple bounds. 类型参数可以有多个边界。 For example 例如
public static <T extends Number & Comparable<T>> T maximum(T x, T y, T z)
The T
is a type parameter passed to the generic class Box and should be subtype of Number class and must implments Comparable interface. T
是传递给泛型类Box的类型参数,应该是Number类的子类型,并且必须包含Comparable接口。 In case a class is passed as bound, it should be passed first before interface otherwise compile time error will occur. 如果一个类以绑定方式传递,则应在接口之前首先传递它,否则将发生编译时错误。
public static <T extends Number & Comparable<T>> T maximum(T x, T y, T z) {
T max = x;
if(y.compareTo(max) > 0) {
max = y;
}
if(z.compareTo(max) > 0) {
max = z;
}
return max;
}
#4楼
Actually, you can do what you want. 实际上,你可以做你想做的事。 If you want to provide multiple interfaces or a class plus interfaces, you have to have your wildcard look something like this: 如果要提供多个接口或类加接口,则必须使用通配符,如下所示:
<T extends ClassA & InterfaceB>
See the Generics Tutorial at sun.com, specifically the Bounded Type Parameters section, at the bottom of the page. 请参阅sun.com上的Generics Tutorial ,特别是页面底部的Bounded Type Parameters部分。 You can actually list more than one interface if you wish, using & InterfaceName
for each one that you need. 如果您愿意,您实际上可以列出多个接口,并为您需要的每个& InterfaceName
使用& InterfaceName
。
This can get arbitrarily complicated. 这可能会变得任意复杂。 To demonstrate, see the JavaDoc declaration of Collections#max
, which (wrapped onto two lines) is: 要演示,请参阅Collections#max
#max的JavaDoc声明,其中(包含在两行中)是:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
why so complicated? 为什么这么复杂? As said in the Java Generics FAQ: To preserve binary compatibility . 正如Java Generics FAQ中所述: 保持二进制兼容性 。
It looks like this doesn't work for variable declaration, but it does work when putting a generic boundary on a class. 看起来这对变量声明不起作用,但是当在类上放置泛型边界时它确实有效。 Thus, to do what you want, you may have to jump through a few hoops. 因此,为了做你想做的事,你可能不得不跳过几个圈。 But you can do it. 但你可以做到。 You can do something like this, putting a generic boundary on your class and then: 你可以这样做,在你的类上放置一个通用的边界,然后:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
to get variable
that has the restriction that you want. 获取具有所需限制的variable
。 For more information and examples, check out page 3 of Generics in Java 5.0 . 有关更多信息和示例,请查看Java 5.0中泛型的第3页。 Note, in <T extends B & C>
, the class name must come first, and interfaces follow. 注意,在<T extends B & C>
,类名必须首先出现,接口跟随。 And of course you can only list a single class. 当然,你只能列出一个班级。