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

时间:2009-04-13 23:21:54

标签: java class generics bounded-wildcard

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

我能做到:

Class<? extends ClassA>

或者:

Class<? extends InterfaceB>

但我不能两者兼顾。有没有办法做到这一点?

4 个答案:

答案 0 :(得分:554)

实际上,你可以做你想做的事。如果要提供多个接口或类加接口,则必须使用通配符:

<T extends ClassA & InterfaceB>

请参阅页面底部的sun.com上的Generics Tutorial,特别是Bounded Type Parameters部分。如果您愿意,您实际上可以列出多个界面,对于您需要的每个界面使用& InterfaceName

这可能会变得任意复杂。为了演示,请参阅Collections#max的JavaDoc声明,其中包含(包含在两行中):

public static <T extends Object & Comparable<? super T>> T
                                           max(Collection<? extends T> coll)
为什么这么复杂?正如Java Generics FAQ中所述:To preserve binary compatibility

看起来这对变量声明不起作用,但是当在类上放置泛型边界时它确实有效。因此,为了做你想做的事,你可能不得不跳过几个圈。但你可以做到。你可以这样做,在你的班级上设置一个通用的边界,然后:

class classB { }
interface interfaceC { }

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

获取具有您想要的限制的variable。有关更多信息和示例,请查看Generics in Java 5.0的第3页。注意,在<T extends B & C>中,类名必须首先出现,接口如下。当然,你只能列出一个班级。

答案 1 :(得分:15)

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

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

答案 2 :(得分:0)

类型参数可以具有多个边界。 例如

public static <T extends Number & Comparable<T>> T maximum(T x, T y, T z)

T是传递给泛型类Box的类型参数,应为Number类的子类型,并且必须包含Comparable接口。如果将类作为绑定传递,则应在接口之前先传递它,否则会发生编译时错误。

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;      
}

了解更多here

答案 3 :(得分:0)

这是您在科特林要做的事情

fun <T> myMethod(item: T) where T : ClassA, T : InterfaceB {
    //your code here
}