具有多个类的Java泛型通配符


Answers:


613

实际上,您可以做您想做的事。如果要提供多个接口或一个类加接口,则必须使通配符看起来像这样:

<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>,类名必须位于第一个,然后是接口。当然,您只能列出一个班级。


94
这是有帮助的。值得一提的是,该类必须排在第一位,您不能说“ <T扩展InterfaceB&ClassA>”。
EricS 2012年

5
对于T应该扩展类还是实现接口,您如何做呢?
拉古纳斯·贾瓦哈尔(Ragunath Jawahar)

1
@RagunathJawahar:你对此不能太开放。您必须有一些界限,其中之一是事先知道您将在何处拥有接口,在何处拥有类以及如何使用继承。对于类型参数,您几乎必须知道它是类还是接口。
艾迪

4
答案的第一行说“使通配符看起来像这样”。?该表达式中没有,所以它真的是“通配符”吗?我之所以问是因为,当类型参数确实是通配符时,我无法使整个“同时扩展两件事”的概念起作用。
The111 2015年

1
是的,它实际上不是通配符,您不能执行OP要求的通配符。您可以有效地执行OP想要的操作,而不必使用通配符。
艾迪(Eddie)

17

您不能使用“匿名”类型参数(即使用的通配符?)来执行此操作,但是可以使用“命名”类型参数来执行此操作。只需在方法或类级别声明类型参数。

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

2
为什么不允许使用通配符?即我不明白为什么这应该是无效的:ArrayList <?扩展ClassA和InterfaceB>列表;然后,如果您从列表中拉出一个元素,则可以将其分配给ClassA或InterfaceB类型的变量
Mark

用变量替换通配符是一个很棒的技术!但这并不总是有效。例如,Java不允许注释值类型中的名称类型变量,而允许通配符。
sigpwned
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.