2011-10-06 228 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”是一个原语。