簡體   English   中英

泛型中的超類型轉換(獲取泛型類型的泛型超類型)

[英]Supertype casting in generics (Getting the generic supertype of a generic type)

這是我使用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(擴展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並且它導致堆棧溢出

這是一種可以解決您的問題的迭代方法:

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

當你創建一個新的A並在你的代碼中傳遞它時,無論你做什么,你的對象都將永遠保持為A.

像轉換和泛型這樣的東西只是告訴編譯器你期望什么類對象但不以任何方式改變對象行為的方法。 因此,我沒有看到你想要通過“將其視為類型T”來實現,但實現這一目標的唯一方法就是像你在沒有泛型的例子中那樣傳遞類型。

PS:永遠記住:Java泛型只是編譯器確保類型安全的一種方式,但在編譯代碼中不會有任何痕跡!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM