泛型中的超类型转换(获取泛型类型的泛型超类型)

时间:2013-08-30 08:32:53

标签: java generics

这是我使用 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

能够 Generics ,如下所示:

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

我可以使用Generics执行相同操作吗?我尝试声明为<S, T extends S>,然后转换为(S)input,但S始终等于{{1}它会导致堆栈溢出

2 个答案:

答案 0 :(得分:3)

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

public static <T> void iterateOverSupertypes(T input) {
    Class<?> clazz = input.getClass();
    while (clazz.getSuperclass() != null) {
        clazz = clazz.getSuperclass();
    }
}

答案 1 :(得分:2)

当你创建一个新的A并在你的代码中传递它时,无论你做什么,你的对象都将永远保持为A.

像cast和泛型这样的东西只是告诉编译器你期望的对象类但不以任何方式改变对象行为的方法。因此,我没有看到你想要通过“将其视为类型T”来实现,但实现这一目标的唯一方法就是像你在没有泛型的例子中那样传递类型。

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