2012-12-27 106 views
1

是否有方法在構造函數中找到泛型類型?在java中獲取構造函數中的泛型類型

public class geneticarg { 
    public static void main(String[] args) { 
    a<String> a1 = new a<String>("a"); 
    a<String> a2 = new a<String>(null); // gives NPE 
    System.out.println(a1.getClazz()); 
    } 
} 

class a<T> { 

private Class<T> clazz; 
private T element; 

public a(T clazz) { 
this.clazz = (Class<T>) clazz.getClass(); 
this.element = clazz; 
// what if clazz is null ? 

} 
//getter and setter 
} 

編輯:這是沒有必要總是字符串來。

+4

由於類型擦除不可能http://docs.oracle.com/javase/tutorial/java/generics/erasure.html – gefei

+0

可以反射在這裏做一些魔術? –

+1

泛型類型被編譯器清除 – gefei

回答

3

在你的情況下避免類型擦除的唯一方法是使用泛型超類。您需要繼承您的泛型類型,然後您可以訪問參數化類型,它可以通過反射API獲得:

public abstract class a<T> { 

    private Class<T> clazz; 
    private T element; 

    public a(T obj) { 
     ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass(); 
     this.clazz = (Class<T>) type.getActualTypeArguments()[0]; 
     this.element = obj; 
    } 
} 

class StringA extends a<String> { 
    public StringA(String obj) { 
     super(obj); 
    } 
} 
+0

你可以簡單地完成這個。 clazz =(類)obj.getClass()'在構造函數中。 – bowmore

+0

你會得到NPE當空傳遞,看問題的第4行 – hoaz

+0

好吧,+1教我:)雖然內省的作品,它的需要表明設計問題。 – bowmore

3

您必須在構造函數中傳遞該類型。您可以使用靜態因子來避免將其設置兩次。

A<String> a1 = A.wrap("a"); 
A<String> a2 = A.forClass(String.class); 

class A<T> { 
    private final Class<T> clazz; 
    private final T element; 

    private A(T t, Class<T> clazz) { 
     this.clazz = clazz; 
     this.element = t; 
    } 

    public static <T> A<T> wrap(T t) { 
     return new A<T>(t, (Class) t.getClass()); 
    } 

    public static <T> A<T> forClass(Class<T> clazz) { 
     return new A<T>(null, clazz); 
    } 

    //getter and setter 
} 
0

彼得是非常正確的。我想添加一些更多信息:

傳入構造函數的Class<T>實例稱爲類型令牌

相關問題