小结:关于得到泛型的Class

总结:关于得到泛型的Class

获得类的泛型:

有一个类:

public class Test<T>    
{    

}  

 

 

现在想获得T的Class。在JAVA目前的泛型机制下,不可能。(原因参见JAVA泛型机制。说白了就是泛型是在编译期获得的,而且有擦除机制。所以在编译前,JAVA也不知道T是啥,编译后,JAVA知道了然后忘记了。囧)

 

网上流传过一个方法,就是写下一个Test类的子类,然后在子类中调用类似

 

Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];   

 

这样的代码来获得T的Class 。 遗憾的是,这是个笑话,或者说没有满足我们的需求,因为要想用上面的代码,Test的子类必须这么写:

public class SonOfTest extends Test<String>{
	
}

否则会报类型转换异常:sun.reflect.generics.reflectiveObjects.TypeVariableImpl

仔细看上面的SonOfTest,你会发现 Test<String>这一段。就是说在继承的时候我们必须事先知道T的类型是String.

并且为String专门做一个子类。这样一来就利用多态机制绕过了这个问题。泛型的可能性少,这方法有用,如果很多的话,为每一个可能性都写个对应的子类那是坑爹呢。

 

所以我在这里遗憾的告诉大家,这是个死穴。

当然在这里我们还能用一个变通的方法解决我们的问题,就是不用泛型机制了,绕过去(当然这个方法也许不优美或者不一定适用)。

 

我们只要把Test类改造成下面这样:

public class Test<T> {
    private Class<T> clazz; //这就是我们想要得到的T的Class    
    
    public Test(Class<T> clazz)    
    {    
        this.clazz = clazz;   //T的Class就是这么得到的,囧
    }    

}

 是的,很简单,就是在Test构造的时候直接通过参数把T的Class告知就行。

使用的时候是这样的: 

Test<String> test = new Test(String.class);

 

别打我。这是没办法的办法。话说回来,你既然在创建Test的时候,已经知道泛型的Class是个String,何苦不用简单的参数形式来获得,而非要用走不通的路去获得它呢?

 

获得方法参数的泛型:

想获得某个类的方法或者成员的泛型,就很简单,应为JAVA提供了方法,抛砖引玉:

					String genericType = method.getGenericParameterTypes()[0].toString().split("<")[1].split(">")[0];
					System.out.println(genericType);