4

这是我尝试使用Java Generics进行的简化示例。

void <T> recursiveMethod(T input) {
    //do something with input treating it as type T
    if (/*need to check if T has a supertype*/) {
        recursiveMethod((/*need to get supertype of T*/) input);

        // NOTE that I am trying to call recursiveMethod() with
        // the input object cast as immediate supertype of T.
        // I am not trying to call it with the class of its supertype.
        // Some of you seem to not understand this distinction.
    }
}

如果我们有一长串类型A extends B extends C (extends Object),调用recursiveMethod(new A())应该执行如下:

recursiveMethod(A input)
 -> A has supertype B
recursiveMethod(B input)
 -> B has supertype C
recursiveMethod(C input)
 -> C has supertype Object
recursiveMethod(Object input)
 -> Object has no supertype -> STOP

可以在没有泛型的情况下做到这一点,如下所示:

void recursiveMethod(Object input) {
    recursiveMethod(input.getClass(), input);
    }
}

private void recursiveMethod(Class cls, Object input) {
    //do something with input treating it as class 'cls'
    if (cls != null) {
        recursiveMethod(cls.getSuperclass(), input);
    }
}

我可以使用泛型做同样的事情吗?我尝试过声明为<S, T extends S>,然后强制转换为(S)inputS总是等于T,这会导致堆栈溢出

4

2 回答 2

3

这是一种可以解决您的问题的迭代方法:

public static <T> void iterateOverSupertypes(T input) {
    Class<?> clazz = input.getClass();
    while (clazz.getSuperclass() != null) {
        clazz = clazz.getSuperclass();
    }
}
于 2013-08-30T08:39:02.320 回答
2

当您创建一个新的 A 并在代码中传递它时,无论您做什么,您的对象都将始终保持为 A。

诸如强制转换和泛型之类的东西只是告诉编译器你期望什么类的对象的方法,但不会以任何方式改变对象的行为。因此,我看不到您通过“将其视为 T 类型”来尝试实现的目标,但我可以看到实现这一目标的唯一方法是像您在示例中所做的那样不使用泛型传递类型。

PS:永远记住:Java泛型只是编译器确保类型安全的一种方式,但编译后的代码中不会有任何痕迹!!!!

于 2013-08-30T09:00:55.697 回答