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



这是我尝试使用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扩展B扩展C(扩展对象),调用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)input,但S始终等于T,这会导致堆栈溢出

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

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

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

像类型转换和泛型之类的东西只是告诉编译器你期望的对象是什么类的方法,但不会以任何方式改变对象的行为。所以我看不出你试图通过"将其视为类型t"来实现什么,但我能看到的实现这一点的唯一方法是像你在没有泛型的例子中所做的那样传递类型。

附言:永远记住:Java泛型只是编译器确保类型安全的一种方式,但在编译的代码中不会有任何它们的踪迹!!!!

最新更新