簡體   English   中英

僅在運行時知道類型的Java泛型的用法

[英]Usage of Java generics when the type is known only at runtime

考慮以下代碼:

public class Generics {
    C c; // initialized at runtime

    public void testGenericsCall(Object o) {
        c.myMethod(o);
    }
}

class C<E> {
    public void myMethod(E input) {
    }
}

這是可行的,但是我得到警告,因為參數化的類C與原始類型一起使用。 我不能使用這樣的聲明

C<String> c;

因為C的類型僅在運行時才知道。 我也不能向泛型類添加類型參數,因為我需要在知道C的類型之前創建此類的對象。

C<?> c;

要么

C<? extends Object> c;

對於編譯器來說是可以的,但是方法testGenericsCall不會編譯( “無法通過方法調用轉換將實際參數java.lang.Object轉換為?的capture#1”

處理這種情況的最佳方法是什么?

編輯 :請注意,當我實際(在運行時)創建C的實例時,我知道它的類型參數,這部分代碼是類型安全的,並且運行良好。 在真實的代碼中,我沒有一個單獨的“ C”類,而是一系列相互關聯的類,並且那里的泛型絕對有用(即使在此簡化示例中這並不明顯-所以請不要僅僅告訴我不要使用泛型:)。 我已經有了編譯時的類型安全性,但是這里沒有,但是在C和其他類之間(這里未顯示)。

我知道在這種情況下如何無法在編譯時檢查type參數,這就是為什么我嘗試將其聲明為C<?> c 在這里, 我只是在尋找沒有編譯器警告而橋接通用和非通用代碼的最佳方法。

由於類型為Erase ,因此無法在運行時使用泛型。 您必須以編程方式處理數據類型,方法是檢查類型或其他任何類型(可能是反射)。

你能行的。 但是通過骯臟的把戲和反思。 例如,看下面的代碼。 禮貌在這里

class ParameterizedTest<T> {

/**
 * @return the type parameter to our generic base class
 */
@SuppressWarnings("unchecked")
protected final Class<T> determineTypeParameter() {
    Class<?> specificClass = this.getClass();
    Type genericSuperclass = specificClass.getGenericSuperclass();
    while (!(genericSuperclass instanceof ParameterizedType) && specificClass != ParameterizedTest.class) {
        specificClass = specificClass.getSuperclass();
        genericSuperclass = specificClass.getGenericSuperclass();
    }
    final ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;

    final Type firstTypeParameter = parameterizedType.getActualTypeArguments()[0];
    return (Class<T>) firstTypeParameter;
}



}

//change the type of PrameterizedTest<Integer> to Parameterized<String> or something to    display different output
public class Test extends ParameterizedTest<Integer>{
 public static void main(String... args){
    Test test = new Test();
    System.out.println(test.determineTypeParameter());
}

}

在運行時,您將在此處獲得類型參數。 因此,在類中,您必須定義一個Class對象,該對象將如上所述獲取類。 然后使用Class.newInstance獲得一個新的Object。 但是您將必須手動處理類型轉換。

問題是:這一切值得嗎?

根據我的說法,不,因為可以通過使用泛型類型中的邊界並與綁定類型進行接口來避免大多數情況

暫無
暫無

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

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