[英]Java Generics Reflection: Generic field type of subclass
給出兩個這樣的類:
class Example1<A,B> {
public Map<A,B> someMap = new HashMap<A,B>();
}
class Example2 extends Example1<URL, URL> {
}
有沒有辦法使用反射我可以確定Example2的Map的組件類型?
我知道我能做到:
ParameterizedType t = (ParameterizedType) Example2.class.getFields()[0].getGenericType();
但是從那里,我似乎無法弄清楚這兩個組件是URL。
有沒有人有任何想法?
達隆並不完全正確。 以下將打印出您想要的內容:
ParameterizedType superClass = (ParameterizedType) Example2.class.getGenericSuperclass();
System.out.println(superClass.getActualTypeArguments()[0]);
System.out.println(superClass.getActualTypeArguments()[1]);
打印出來:
class java.net.URL
class java.net.URL
由於Java泛型是通過“擦除”實現的,因此在運行時通過反射無法獲得此信息。
編輯:似乎我錯過了一些問題的細節。 在這種特殊情況下,可以獲得類型信息。
你的答案不太正確 - 你正在返回類的泛型類型,而不是“someMap”字段類型。
當然,在給定someMap的參數的示例中,它們與類的參數相同,但是如果someMap被定義為,並且地圖類型不是兩個URL,那么有一個關於如何映射泛型類型的字段參數。
一個更好的例子可能是:
class Example1<A,B> {
public Map<B,A> someMap = new HashMap<B,A>();
}
class Example2 extends Example1<URL, String> {
}
在這種情況下,回答問題:Example2中的某些Map的類型是什么? 答案應該是:
java.lang.String java.net.URL
但是,我仍然無法弄清楚如何做到這一點。
Java反射API沒有直接提供所需內容的方法,但它確實暴露了使用Field.getGenericType()
和Class.getGenericSuperclass()
計算它所需的所有基本信息。 但是,對於任何類層次結構和字段類型,一般來說解決這個問題並非易事。
要做到這一點計算 ,你可以使用gentyref庫。 在您的示例中,您可以像這樣獲取someMap變量的類型:
Type someMapType = GenericTypeReflector.getExactFieldType(
Example2.class.getField("someMap"),
Example2.class);
如果有足夠的信息(在Example2中,它是),someMapType將是ParameterizedType 。 然后你可以得到鍵的類型和值,如下所示:
((ParameterizedType)someMapType).getActualTypeArguments();
這將是包含URL.class
兩次的數組。 請注意,它也可以包含除類之外的其他內容(例如,另一個ParameterizedType)。 因此,如果你想用這種類型做一些非平凡的事情(例如,看看它是否是另一種類型的超類型),GenericTypeReflector中的其他方法也可以派上用場......
[我是gentyref的作者]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.