2011-10-06 130 views
0

所以我有以下的通用類:如何獲取泛型類的對象類型?

public class Member<T> { 

private T id; 
private T complexityLevel; 

//constructor 
public Member(T id, T complexityLevel) { 
    this.id = id; 
    this.complexityLevel = complexityLevel; 
} 


public T getId() { 
    return id; 
} 

public T getComplexity() { 
    return complexityLevel; 
} 

public void setComplexity(T complexityLevel) { 
    this.complexityLevel = complexityLevel; 
} 

public void setId(T id) { 
    this.id = id; 
} 

public static void main(String[] args) { 
    Member<String> mString = new Member<String>("id1", "High"); 
    System.out.printf("id before setting id: %s%n", mString.getId()); 
    mString.setId("id2"); 
    System.out.printf("id after setting id: %s%n", mString.getId()); 

    System.out.printf("complexity before setting it: %s%n", mString.getComplexity()); 
    mString.setComplexity("Low"); 
    System.out.printf("complexity after setting it: %s%n", mString.getComplexity()); 


    // now for an integer 

    Member<Integer> mInteger = new Member<Integer>(1, 100); 
    System.out.printf("id before setting id: %d%n", mInteger.getId()); 
    mInteger.setId(2); 
    System.out.printf("id after setting id: %d%n", mInteger.getId()); 


    // for Double 

    Member<Double> mDouble = new Member<Double>(100.0); 
    ... 

我試圖獲得Member類的對象基本類型(StringIntegerDouble等)。到目前爲止,我有這一點,但問題是它返回"Member"

System.out.println(mString.getClass().getName()); 
System.out.println(mInteger.getClass().getName()); 
System.out.println(mDouble.getClass().getName()); 

回答

2

你不能在運行時確定泛型類型,由於type erasure。爲了使這種信息擦除之後保存,Member<T>需要採取在其構造器一個Class<T>對象,並抓住它:

public class Member<T> { 

public final Class<T> type; 

private T id; 
private T complexityLevel; 

//constructor 
public Member(T id, T complexityLevel, Class<T> type) { 
    id = id; 
    this.complexityLevel = complexityLevel; 
    this.type = type; 
} 

再後來:

Member<String> mString = new Member<String>("id1", "High", String.class); 

... 

System.out.println(mString.type.getName()); 

另外,如果id保證從不是null,您可以使用反射來檢索代表其類型的對象Class

System.out.println(mString.getId().getClass().getName()); 

當然getClass()將返回Class<? extends T>。因此,如果id實際上是T的子類,那麼您將獲得該類的名稱,而不是名稱T

+0

謝謝。我得到「java.lang.String」,「java.lang.Integer」和「java.lang.Double」。我可以用它來獲取子字符串。基本上我需要確定我正在執行的測試用例的參數類型。 – nabsATX

+0

@neal_fazio - 你問如何得到「字符串」,「整數」等?你可以使用'getSimpleName()'而不是'getName()'。 –

+0

完美。我想我需要熟悉一些更多的Java API。 – nabsATX

3

該信息(泛型類型T)在編譯(類型擦除)過程中被剝離。

使用super type tokens是一種適度疼痛的技術,可以在這裏應用。 Guice的TypeLiteral就是一個例子。

另外,String和Integer不是原始類型。 「int」是一個原語。