GenericDeclaration接口的研究

 

这几天看class类的代码,对泛型有了一点理解,在这里与大家分享一下。

 

首先我们来看一个非常简单的泛型

 

public class TestA<K extends List & Serilizable, V> {
  ...
}

 在这个类中<K extends List & Serilizable, V>称为泛型变量。

 

K extends List & Serilizable的意思是K这个泛型是有上界的,它必须是一个继承List以及Serilizable的类或接口。

 

 

说完这些我们在来看看class类,class类继承的和泛型有关的接口有GenericDecalaration以及Type

 

 

GenericDecalaration接口是说明哪些类的对象可以通过反射机制来获取泛型声明,它有三个实现类,分别是Cass, Constructor, Method

可能我们会奇怪为什么没有Object类,那是因为Object类有一个

public final native Class<?> getClass();方法。

通过调用这个方法我们可以返回一个Class类型的对象

以下面这个例子为例:

 

public class Test {
	public static void main(String[] args) {
		Test t = new Test();
		Class<? extends Test> c = t.getClass();
		System.out.println(c.getName());         //输出Test
	}
}

 我们定义了一个Test类,然后生成了一个实例化对象t,通过getClass方法我们获得了t的运行时类对象c,这个是c就是Class类型的。我们试图将它输出到控制台,显示的结果正好就是Test——我们自定义的类的名称。

 

 

 

所以说每一个Object类的子类都可以通过getClass来获得其对应的运行时类对象。Class类实现了GenericDecalaration接口就约等于所有Object的子类都实现了GenericDecalaration接口了。

 

 

那么实现GenericDecalaration接口有什么用呢?GenericDecalaration接口有一个

public TypeVariable<?>[] getTypeParameters();方法

这个方法返回的泛型变量数组代表了泛型声明的内容,TypeVariable类型就是定义泛型变量的。

以下面这个例子为例:

 

public class Test<K extends List & Serializable, V> {
	public static void main(String[] args) {
		Test t = new Test();
		TypeVariable[] tvarg = t.getClass().getTypeParameters();
		System.out.println("tvarg.lenght=" + tvarg.length);       //tvarg.lenght=2
	}
}

 我们可以看到通过getTypeParameters方法返回了一个长度为2的数组,他们分别表示了

 

<K extends List & Serializable, V>

泛型变量中的

KVextends List & Serializable应该属于修饰)

 

 

从下面开始我们就要来分析一下泛型变量TypeVariable接口

TypeVariable总共有三个方法

Type[] getBounds();

D getGenericDeclaration();

String getName();

 

 

Type[] getBounds();方法很好理解,就是返回当前类型的边界,

以刚刚的例子为例extends List & Serializable,那k的边界就应该是ListSerializable

用下面的例子来试验一下

public class Test<K extends List & Serializable, V> {
	public static void main(String[] args) {
		TypeVariable[] tvarg = new Test().getClass().getTypeParameters();
		Type[] typearg = tvarg[0].getBounds();
		System.out.println("typearg.lenght=" + typearg.length);
		for (int i = 0; i < typearg.length; i++) {
			System.out.println(typearg[i].toString());
		}
	}
}

 我们看到控制台先输出了typearg.lenght=2说明有两个上边界。然后分别输出了两个边界的类型。

D getGenericDeclaration();方法则是返回在哪一个类上面进行了泛型的声明(我们看这个方法的名字直译是“获取通用声明”,但返回的却是一个在代码中具有声明的类的运行时类对象。我们可以这样理解,Class类型实现了GenericDeclaration接口,那我们要看声明的代码就要往这个Class上找,可以看成是一种提示吧。

以下面的例子为例

public class Test<K extends List & Serializable, V> {
	public static void main(String[] args) {
		TypeVariable[] tvarg = new Test().getClass().getTypeParameters();
		GenericDeclaration gd0 = tvarg[0].getGenericDeclaration();
		GenericDeclaration gd1 = tvarg[1].getGenericDeclaration();
		System.out.println("gd0=" + gd0.toString());
		System.out.println("gd1=" + gd1.toString());
	}
}

 在控制台直接显示了这个泛型是声明在Test这个类。

最后String getName();方法返回的是泛型变量的名称,就一刚刚那个例子为例,然后的就是KV

 

public class Test<K extends List & Serializable, V> {
	public static void main(String[] args) {
		TypeVariable[] tvarg = new Test().getClass().getTypeParameters();
		System.out.println("tvarg0=" + tvarg[0].getName());
		System.out.println("tvarg1=" + tvarg[1].getName());
	}
}

 通过这几个方法我们就可以利用反射机制来动态获取类型的泛型声明了。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值