我想要一个Class对象,但我想强制使用它表示的任何类来扩展类A和实现接口B。
我可以:
Class<? extends ClassA>
要么:
Class<? extends InterfaceB>
但我不能两者都做。有没有办法做到这一点?
我想要一个Class对象,但我想强制使用它表示的任何类来扩展类A和实现接口B。
我可以:
Class<? extends ClassA>
要么:
Class<? extends InterfaceB>
但我不能两者都做。有没有办法做到这一点?
Answers:
实际上,您可以做您想做的事。如果要提供多个接口或一个类加接口,则必须使通配符看起来像这样:
<T extends ClassA & InterfaceB>
请参见sun.com上的泛型教程,特别是页面底部的“ 绑定类型参数”部分。如果需要,实际上可以列出一个以上的界面,& InterfaceName
用于所需的每个界面。
这会变得任意复杂。为了演示,请参阅的JavaDoc声明Collections#max
(分为两行)为:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
为什么这么复杂?如Java泛型常见问题解答中所述:保留二进制兼容性。
看起来这不适用于变量声明,但是在类上放置通用边界时确实起作用。因此,要做您想做的事情,您可能不得不跳过几圈。但是你可以做到的。您可以执行以下操作,在类上放置通用边界,然后:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
得到variable
具有您想要的限制。有关更多信息和示例,请查看Java 5.0中泛型的第3页。请注意,在中<T extends B & C>
,类名必须位于第一个,然后是接口。当然,您只能列出一个班级。
?
该表达式中没有,所以它真的是“通配符”吗?我之所以问是因为,当类型参数确实是通配符时,我无法使整个“同时扩展两件事”的概念起作用。
您不能使用“匿名”类型参数(即使用的通配符?
)来执行此操作,但是可以使用“命名”类型参数来执行此操作。只需在方法或类级别声明类型参数。
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}