java 泛型 深入(二)

2014-11-24 09:12:31 · 作者: · 浏览: 4
泛型类型,这就使得获取泛型的实际类型参数成为

了可能,下面来看一段代码,这段代码很精辟,很有用,大家一定要学到手哈:


package test;

import java.lang.reflect.ParameterizedType;
/**
* -----------------------------------------
* @描述 泛型的实际类型参数
* @作者 fancy
* @邮箱 fancydeepin@yeah.net
* @日期 2012-8-25


* -----------------------------------------
*/
public class Base {

private Class entityClass;

//代码块,也可将其放置到构造子中
{
entityClass =(Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

}

//泛型的实际类型参数的类全名
public String getEntityName(){

return entityClass.getName();
}

//泛型的实际类型参数的类名
public String getEntitySimpleName(){

return entityClass.getSimpleName();
}

//泛型的实际类型参数的Class
public Class getEntityClass() {
return entityClass;
}

}

以上代码的精华全在这句:(Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

实际上,这句话咋看起来很难看的明白,理解起来就更加的吃力了,下面容我来将这句复杂的代码拆分开来,理解起来可能会好些:


//代码块,也可将其放置到构造子中
{
//entityClass =(Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
try {
Class< > clazz = getClass(); //获取实际运行的类的 Class
Type type = clazz.getGenericSuperclass(); //获取实际运行的类的直接超类的泛型类型
if(type instanceof ParameterizedType){ //如果该泛型类型是参数化类型
Type[] parameterizedType = ((ParameterizedType)type).getActualTypeArguments();//获取泛型类型的实际类型参数集
entityClass = (Class) parameterizedType[0]; //取出第一个(下标为0)参数的值
}
} catch (Exception e) {
e.printStackTrace();
}

}

注意,获取 Class 实例的时候是用 getClass(),而不是用 Base.class,获取 Class 的方式有三种,这是其中的两种,还有一种是 Class.forName("类全名"),如需了解反射的基础知识

请前往上一篇随笔 java 反射基础

那么,Base.class 与 getClass(),这两个方法来获取类的字节码的时候,有什么不一样的地方呢?当然有不一样的地方了,Base.class 是写死了的,它得到的永远是 Base 类的字节码,

而 getClass() 方法则不同,在上面代码注释中的第一、二行注释我用了“实际运行的类”6个字,这几个字很重要,一定要理解,如果无法理解,下面的你可能就看不懂了。

为了方便大家的理解,下面插加一个小例子来加以说明 类.class 与 getClass() 两种方法来获取类的字节码有什么区别:


package test;
/**
* -----------------------------------------
* @描述 超类
* @作者 fancy
* @邮箱 fancydeepin@yeah.net
* @日期 2012-8-25


* -----------------------------------------
*/
public class Father {

public Father (){

System.out.println("Father 类的构造子:");
System.out.println("Father.class :" + Father.class);
System.out.println("getClass() :" + getClass());
}

}


package test;

/**
* -----------------------------------------
* @描述 超类的子类(超类的实现类)
* @作者 fancy
* @邮箱 fancydeepin@yeah.net
* @日期 2012-8-25


* -----------------------------------------
*/
public class Children extends Father{


}


package test;
/**
* -----------------------------------------
* @描述 测试类
* @作者 fancy
* @邮箱 fancydeepin@yeah.net
* @日期 2012-8-25


* -----------------------------------------
*/
public class Test {

public static void main(String[] args){

new Children(); //实际运行的类是Children(Father类的子类或者说是实现类)
}

}

后台打印输出的结果:

Father 类的构造子:
Father.class :class test.Father
getClass() :class test.Children

从打印出的结果看来,类.class 与 getClass() 的区别很明了了,getClass() 获取的是实际运行的类的字节码,它不一定是当前类的 Class,有可能是当前类的子类的 Class,具体是哪

个类的 Class,需要根据实际运行的类来确定,new 哪个类,getClass() 获取的就是哪个