我知道如何使用反射來訪問泛型類型的字段:只需檢查field.getGenericType() instanceof ParameterizedType
。在運行時訪問對象的泛型類型
但是,如何檢查相同的任意對象,不知道它在哪裏宣佈?
我知道如何使用反射來訪問泛型類型的字段:只需檢查field.getGenericType() instanceof ParameterizedType
。在運行時訪問對象的泛型類型
但是,如何檢查相同的任意對象,不知道它在哪裏宣佈?
泛型適用於變量聲明,方法返回類型等,而不是對象本身。您可以通過myObj.getClass().getTypeParameters()
確定特定對象的Class
是否使用泛型,但無法確定使用哪種類型參數的值創建特定對象實例。
對象不存儲的通用信息本身,所以new ArrayList<Integer>()
生成的字節碼是完全一樣的一個new ArrayList<String>()
。我的意思是正好是。這就是Java泛型的類型擦除。他們只是傾向於new ArrayList()
。
但是,在幾乎所有其他情況下,類型參數被保留,如字段/參數/返回類型聲明。其中一個被保留的情況是而不是被刪除是一個類的超類。所以如果你創建一個擴展爲ArrayList<String>
的類,你可以在運行時訪問這些信息。
但這似乎矯枉過正,不是嗎?一個延伸ArrayList<String>
的新類和另一個延伸ArrayList<String>
等的類似乎不切實際。匿名內部類可以使這更容易。所以,如果你想保留通用信息,你只需要做new ArrayList<String>() {}
而不是new ArrayList<String>()
。您可以在創建的對象上調用getClass().getGenericSuperclass()
以獲取通用信息。
我並不是想讓他們自己做,而是爲了恢復普通類型的用戶以序列化的形式傳輸對象...我想這是不可能的以適當的方式。一種盡力而爲的方法是檢查一個類是否使用泛型類型,如果是,檢查是否有內部使用它們的字段。使用實例和這些字段,可以重構使用的泛型類型。但對於我的工作,我猜這是一種矯枉過正的... –
+1:這與[番石榴的'TypeToken']使用的技術相同(http://docs.guava-libraries.googlecode.com/git/的Javadoc/COM /谷歌/普通/反映/ TypeToken.html)。 –
@IanRoberts是Guava使用相同的技術。我相信這是2006年最初在這個模式上發表過博文的Neal Gafter。他稱之爲[Super Type Tokens](http://gafter.blogspot.de/2006/12/super-type-tokens.html)模式。在我看來,Java社區有點低估了。 – Saintali
不輸入擦除類型排除了這種可能性嗎? – cdhowie
問題是:'getGenericType()'是'Field'的一種方法,不能應用於任何'Object' ... –