java 获取接口泛型_java获取泛型信息

总结一下java中获取与泛型相关的信息的知识,不如说是使用方法.网上也有很多类似的优秀文章,这里主要做一个知识的总结.通过反射获取泛型信息的常见例子:

//bean

package testProject;

public class Person {

private String nameString = "233";

public String getNameString() {

return nameString;

}

public void setNameString(String nameString) {

this.nameString = nameString;

}

@Override

public String toString() {

return "Person [nameString=" + nameString + "]";

}

}

//基本dao

public abstract class BaseDao {

private Class clazz = null;

{

Type type = getClass().getGenericSuperclass();

if( type instanceof ParameterizedType ){

ParameterizedType pType = (ParameterizedType)type;

Type claz = pType.getActualTypeArguments()[0];

if( claz instanceof Class ){

this.clazz = (Class) claz;

}

}

}

public T getEntity() throws InstantiationException, IllegalAccessException{

return this.clazz.newInstance();

}

}

//实现

public class PersonDao extends BaseDao {

public static void main(String[] args) throws InstantiationException, IllegalAccessException {

PersonDao pDao = new PersonDao();

System.out.println( pDao.getEntity().toString() );

}

}

//结果:Person [nameString=233]

在java的java.lang.reflect 包中有一个Type接口.  具体子类如下.

java 获取接口泛型_java获取泛型信息_第1张图片

一般java中包含泛型信息的地方包括类( class MyClass )方法( public void test(T t){  } )字段( public List list,public T t),继承的父类中包含( class MyClass1 extends MyClass{} )等.

java将这些泛型信息进行了分类,包括包含泛型信息的类型,不包含泛型信息的类型,泛型数组类型,以及对泛型参数(T,V等泛型参数)信息类等.所有这些分类统一用Type接口作为抽象

class HaveGenericClass{}classNoGenericClass{}public class TypeTest{private Listlist;privateT t;privateList list1;private Listlist2;privateHaveGenericClass haveGenericClassWithoutGeneric;private HaveGenericClasshaveGenericClassWithGeneric;privateNoGenericClass noGenericClass;private int var;private List[] listTArr;private List[] listStringArr;privateList[] listArr;privateT[] tArr;private int[] intArr;privateHaveGenericClass[] haveGenericClassWithoutGenericArr;private HaveGenericClass[] haveGenericClassWithGenericArr;private HaveGenericClass[] haveGenericClassWithGenericArr2;privateNoGenericClass[] noGenericClassArr;private U genericMethod(U u,String s){returnu;

}public static voidmain(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {

Field[] fields= TypeTest.class.getDeclaredFields();for( Field f: fields ){

Type t=f.getGenericType();

printType(f.getName(), t);

}

Method genericMethod= TypeTest.class.getDeclaredMethod("genericMethod",Object.class,String.class);

Type[] types=genericMethod.getGenericParameterTypes();

Parameter[] ps=genericMethod.getParameters();for(Parameter p : ps){

Type type=p.getParameterizedType();

printType(p.getName(), type);

System.out.println( p.getType() );

}

}public static voidprintType(String name, Type type){if( type instanceof Class ){

System.out.println("the type of" + name + "is : Class");

}else if( type instanceof ParameterizedType ){

System.out.println("the type of" + name + "is : ParameterizedType");

}else if( type instanceof GenericArrayType ){

System.out.println("the type of" + name + "is : GenericArrayType");

}else if( type instanceof TypeVariable ){

System.out.println("the type of" + name + "is : TypeVariable");

}

}

}

运行结果如下:

the type of list is : ParameterizedType

the type of t is : TypeVariable

the type of list1 is : Class

the type of list2 is : ParameterizedType

the type of haveGenericClassWithoutGeneric is : Class

the type of haveGenericClassWithGeneric is : ParameterizedType

the type of noGenericClass is : Class

the type of var is : Class

the type of listTArr is : GenericArrayType

the type of listStringArr is : GenericArrayType

the type of listArr is : Class

the type of tArr is : GenericArrayType

the type of intArr is : Class

the type of haveGenericClassWithoutGenericArr is : Class

the type of haveGenericClassWithGenericArr is : GenericArrayType

the type of haveGenericClassWithGenericArr2 is : GenericArrayType

the type of noGenericClassArr is : Class

the type of arg0 is : TypeVariable

class java.lang.Object

the type of arg1 is : Class

class java.lang.String

从上面的测试中可以看到,带有泛型信息的类型可以划分到ParameterizedType类型,类似( List,List等).包含泛型信息的数组则可以划分到GenericArrayType分类,其余不包含泛型信息的类型可以划分到Class类型(可以认为不包含泛型的类型也是一种参数化类型(参数化类型 举个例子就是 class person{ }这样子),只不过这种参数化类型的泛型信息为零(没有泛型信息的参数化类型)),因此Class类也实现Type接口.下面就介绍有一下这4个类的方法和如何获取(仅限我所知道的).

1.ParameterizedType

public interfaceParameterizedType extends Type {

//获取<>中的实际类型Type[] getActualTypeArguments();

//获取<>前的实际类型Type getRawType();

//如果这个类是某个类的所属,返回这个所属的类,否则返回nullType getOwnerType();

}

Type[] getActualTypeArguments();

获取<>中的实际类型,该方法只脱去最外层的<>.

class People{}public class TypeTest{private People,T>People;public static voidmain(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {

Type t= TypeTest.class.getDeclaredField("People").getGenericType();

ParameterizedType pt=(ParameterizedType)t;

Type[] types=pt.getActualTypeArguments();for( int i = 0; i < types.length; i++){

printType(types[i].toString(), types[i]);

}

}public static voidprintType(String name, Type type){if( type instanceof Class ){

System.out.println("the type of" + name + "is : Class");

}else if( type instanceof ParameterizedType ){

System.out.println("the type of" + name + "is : ParameterizedType");

}else if( type instanceof GenericArrayType ){

System.out.println("the type of" + name + "is : GenericArrayType");

}else if( type instanceof TypeVariable ){

System.out.println("the type of" + name + "is : TypeVariable");

}

}

}

执行结果为

the type of class java.lang.String is : Class

the type of java.util.List is : ParameterizedType

the type of T is : TypeVariable

可以看到第二个泛型参数的类型是ParameterizedType,也真是List所对应的类型.另外第三个泛型参数的类型为TypeVariable,泛型参数(T,V等泛型参数)信息类(我是这么解释和理解的)之后会提到.

2.getRawType()

获取声明泛型的实际的类或接口,也就是<>前面的那个值

3.getOwnerType()

如果该类是内部类,那么该方法可以获取外部类,否则返回null, 举个例子

public class TypeTest{private People,T>People;private class Inner{}private Innerinner;public static voidmain(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {

Type t= TypeTest.class.getDeclaredField("inner").getGenericType();

ParameterizedType pt=(ParameterizedType)t;

Type t1=pt.getOwnerType();if( t1 instanceof ParameterizedType ){

ParameterizedType pt1=(ParameterizedType)t1;

System.out.println( pt1.getRawType() );

}

}

}

结果:

class testProject.TypeTest

2.GenericArrayType

泛型数组类型,类似(List[] T[]等).

public interfaceGenericArrayType extends Type {Type getGenericComponentType();

}

返回泛型数组中元素的Type类型,即List[] 中的 List(ParameterizedTypeImpl),T[] 中的T(TypeVariableImpl),List[][]中的List[]();

public class TypeTest{private List[] lists;privateT[] ts;private List[][] listss;public static voidmain(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {

Type lists= ((GenericArrayType)TypeTest.class.getDeclaredField("lists").getGenericType()).getGenericComponentType();

Type ts= ((GenericArrayType)TypeTest.class.getDeclaredField("ts").getGenericType()).getGenericComponentType();

Type listss= ((GenericArrayType)TypeTest.class.getDeclaredField("listss").getGenericType()).getGenericComponentType();

printType("lists", lists);

printType("ts",ts );

printType("listss",listss );

}public static voidprintType(String name, Type type){if( type instanceof Class ){

System.out.println("the type of" + name + "is : Class");

}else if( type instanceof ParameterizedType ){

System.out.println("the type of" + name + "is : ParameterizedType");

}else if( type instanceof GenericArrayType ){

System.out.println("the type of" + name + "is : GenericArrayType");

}else if( type instanceof TypeVariable ){

System.out.println("the type of" + name + "is : TypeVariable");

}

}

}

执行结果如下:

the type of lists is : ParameterizedType

the type of ts is : TypeVariable

the type of listss is : GenericArrayType

3.TypeVariable

泛型的类型变量,可以认为是List中的T,Map中的K,V等

3.1 getBounds()

获取类型变量上限,如果没有上限(即 class Person{},这里的类型变量T 没有上限),那么上限为Object

public class TypeTest>{//继承String,实现接口Comparable,可以用&连接多个接口private List[] lists;privateT[] ts;private List[][] listss;public static void main(String[] args) throwsNoSuchFieldException, SecurityException, NoSuchMethodException {

TypeVariable tv[]= TypeTest.class.getTypeParameters();

Type[] ts= tv[0].getBounds();for( Type t : ts ){

System.out.println( t );

}

}

}

执行结果如下:

class java.lang.String

java.lang.Comparable

3.2 getGenericDeclaration()

获取声明该类型变量的类比如( TypeTest 中的TypeTest )

public class TypeTest{private List[] lists;private List[][] listss;public static void main(String[] args) throwsNoSuchFieldException, SecurityException, NoSuchMethodException {

TypeVariable tv[]= TypeTest.class.getTypeParameters();

System.out.println( tv[0].getGenericDeclaration() );

}

}

执行结果:

class testProject.TypeTest

3.3 getName()

获取类型变量在源码中定义的名称

public class TypeTest{private List[] lists;private List[][] listss;public static void main(String[] args) throwsNoSuchFieldException, SecurityException, NoSuchMethodException {

TypeVariable tv[]= TypeTest.class.getTypeParameters();

System.out.println( tv[0].getName() );

}

}

执行结果:

T

//补充一点

泛型的声明包括在类上方法上或者构造函数上,并不能再字段上声明泛型.

在类上声明:

class Person{

private T t; //字段可以使用声明的泛型

}

在构造函数上声明:

class TypeTest{

public TypeTest(){}

}

在方法上声明:

class TypeTest{

public void test(T t){}

}

但不能直接在字段上声明, 比如

class Person{

private T t;//错误

}

这样的使用方法不正确.

由此及彼,在获取泛型变量的方式上,java提供了一个GenericDeclaration接口

public interfaceGenericDeclaration{

TypeVariable>[] getTypeParameters();

}

用于获取泛型变量,

而实现该接口的继承体现如下

java 获取接口泛型_java获取泛型信息_第2张图片

其中并不包含Field类.

4.Class

Class描述类的字节码信息(即.class文件的信息),包括所描述的类的字段信息,方法信息,注解信息,也包括与泛型有关的信息. 下面只介绍和泛型有关的方法.

public final class Class extendsObjectimplements Serializable,GenericDeclaration,Type,AnnotatedElement

4.1 getTypeParameters

TypeVariable>[] getTypeParameters()

返回类上的泛型信息( 比如Person{},则返回TypeVariable数值标识泛型变量T,U ,如果没有泛型信息则数组长度为零)

class People{

}class Chinese extends People{

}public class TypeTest{public TypeTest(){

}private List[] lists;private List[][] listss;public static void main(String[] args) throwsNoSuchFieldException, SecurityException, NoSuchMethodException {

TypeVariable[] tv= People.class.getTypeParameters();

System.out.println( tv.length );for( TypeVariable t : tv ){

System.out.println( t );

}

TypeVariable[] tv1= Chinese.class.getTypeParameters();

System.out.println( tv1.length );for( TypeVariable t : tv1 ){

System.out.println( t );

}

}

}

执行结果如下:

3

T

V

S

0

4.2 getGenericSuperClass();

返回该类的父类的泛型类型 比如( class Chinese extendis People{},返回的是People,如果没有父类,返回的是Objec的Class实例 )

4.3 getGenericInterfaces();

返回该类的实现的接口们的泛型类型 比如(class Chinese extends People implements SpeakChinese,UseChopsticks{},返回的是SpeakChinese,UseChopsticks,如果没有实现的接口,返回的Type数组长度为0)

代码如下:

interface Walk{}interface SpeakChinese{}interface UseChopsticks{}class People implements Walk{

}class Chinese extends People implements SpeakChinese,UseChopsticks{

}class Mars extends People>{

}public class TypeTest{public TypeTest(){

}public static void main(String[] args) throwsNoSuchFieldException, SecurityException, NoSuchMethodException {

printType(People.class.getGenericSuperclass().toString(), People.class.getGenericSuperclass());

printType(Chinese.class.getGenericSuperclass().toString(), Chinese.class.getGenericSuperclass());

Type[] types= Chinese.class.getGenericInterfaces();

System.out.println( types.length );for(Type t: types){

printType(t.toString(), t);

}

Type[] types1= Mars.class.getGenericInterfaces();

System.out.println( types1.length );for( Type t : types1 ){

printType( t.toString(),t );

}

}public static voidprintType(String name, Type type){if( type instanceofClass ){

System.out.println("the type of " + name + " is : Class");

}else if( type instanceofParameterizedType ){

System.out.println("the type of " + name + " is : ParameterizedType");

}else if( type instanceofGenericArrayType ){

System.out.println("the type of " + name + " is : GenericArrayType");

}else if( type instanceofTypeVariable ){

System.out.println("the type of " + name + " is : TypeVariable");

}

}

}

执行结果如下:

the type of class java.lang.Object is : Class

the type of testProject.People is : ParameterizedType

2

the type of testProject.SpeakChinese is : ParameterizedType

the type of testProject.UseChopsticks is : ParameterizedType

0

以上就是4种类型的介绍.

另外 还有一个接口继承自Type接口

WildcardType

用于描述包含通配符的泛型变量的信息. 比如List extends String> 或者 List super Integer>等

public interface WildcardType extendsType{

Type[] getLowerBounds();

Type[] getUpperBounds();

}

getLowerBounds()

获取泛型变量的下界,

getUpperBounds()

获取泛型变量的上界.

public class TypeTest{private List extends String>upperBoundsList;private List super Integer>lowerBoundsList;public static void main(String[] args) throwsNoSuchFieldException, SecurityException, NoSuchMethodException {

Field upperBoundsList= TypeTest.class.getDeclaredField("upperBoundsList");

ParameterizedType pt=(ParameterizedType)upperBoundsList.getGenericType();

Type[] types=pt.getActualTypeArguments();

System.out.println( ((WildcardType)types[0]).getUpperBounds()[0] );

Field lowerBoundsList= TypeTest.class.getDeclaredField("lowerBoundsList");

ParameterizedType pt1=(ParameterizedType)lowerBoundsList.getGenericType();

Type[] types1=pt1.getActualTypeArguments();

System.out.println( ((WildcardType)types1[0]).getLowerBounds()[0] );

}

}

执行结果如下:

class java.lang.String

class java.lang.Integer

/*---------------------------------------------------------------------------------------------------------------------------------------------------------------*/

以上为本人查阅资料参考网上文章所写,

不能保证完全正确,

也并非面面俱到.

表述方式并不是偏向于专业化(如有疑惑的地方可留言),如有错误,望指正.

参考文档:

http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

http://www.jianshu.com/p/e8eeff12c306

你可能感兴趣的:(java,获取接口泛型)