簡體   English   中英

Java泛型反射:子類的通用字段類型

[英]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.

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