當我運行(ParameterizedType)的getClass()getGenericSuperclass(), 想到被T,但它的PropertyEditorSupport,並且不能被強制轉換爲 ParameterizedType;
如果您想要訪問T
(即類型參數),則適當的反射方法是Class.getTypeParameters
。
// Test.java:
class Generic<T> {
}
class Main {
public static void main(String[] args) {
final Generic<Integer> gint1 = new Generic<Integer>();
System.err.println("gint1's type-parameter: "
+ gint1.getClass().getTypeParameters()[0]);
}
}
如果你運行你上面得到下面的代碼:
$ javac Test.java
$ java Main
gint1's type-parameter: T
注意,類型參數未解析爲整數,但作爲T
因爲這種信息無法在運行時。
如果訪問這些信息對您很重要,那麼您有兩個簡單的選項。
A.對象包含實際類型的類的引用:
class Generic<T> {
public final Class<T> type;
public Generic(Class<T> type) {
this.type = type;
}
public Class<T> type() {
return type;
}
}
class Main {
public static void main(String[] args) {
final Generic<Integer> gint2 = new Generic<>(Integer.class);
System.err.println("gint2's type-parameter: " + gint2.type().getSimpleName());
}
}
// Output will be "gint2's type-parameter: Integer".
B.你創建一個子類,給出了一個具體的類爲該類型的參數:
import java.lang.reflect.*;
class Generic<T> {
}
class IntegerGeneric extends Generic<Integer> {
}
class Main {
public static void main(String[] args) {
final Generic<Integer> gint3 = new IntegerGeneric();
final Generic<Double> gint4 = new Generic<Double>() {};
System.err.println("gint3's type-parameter: "
+ ((ParameterizedType)gint3.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
System.err.println("gint4's type-parameter: "
+ ((ParameterizedType)gint4.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
}
// Output:
// gint3's type-parameter: class java.lang.Integer
// gint4's type-parameter: class java.lang.Double
注意gint4類不是Generic<Double>
,而是由匿名內部類擴展它,由於構造函數後面的{}
...這是完整的class DoubleGeneric ...
聲明的替代方法。
在這兩個替代方案中,A.和B.,A.因爲通常應該避免依賴反思;除此之外,它更容易隱藏運行時錯誤,代碼更難以維護。
我想知道有什麼不同,當使用 (ParameterizedType)的getClass()。getGenericSuperclass()一類具有 一個沒有泛型類型的超類。
如果您查找的Type
文檔,類此方法返回的引用,它表示這是一個「保護傘」超級接口爲所有對象/數據類型可以在Java語言中甚至包括primitives ...所以對於沒有泛型超類的類我想它會返回一個反映該類型的子類...
一個快速實驗顯示,實際上它會返回一個'Class'對象它相當於getSuperclass()。
也許其他人可以對此有更多的瞭解,但我認爲這可能有點誤會......我認爲getSuperType()或類似的東西會更合適。也許最初它只支持較舊的Java版本(1.5版本)中的泛型,並最終擴展到涵蓋其他數據類型,但這是我的一個猜測,而沒有考慮它的歷史。
泛型是編譯時安全檢查。它們在運行時不包含任何可用的類型信息。 – 4castle
@ 4castle但是,如果'RequestDataEditor'類沒有父類,那麼我們可以得到泛型類型 – JackYe
如果刪除'extends PropertyEditorSupport','getGenericSuperclass()'只返回'class Object'。請提供[mcve]進行測試。 – kennytm