Java中泛型与反射的问题

Java泛型:

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

从上面的描述中我么可以知道,Java泛型时作用在编译时期的,用来提供安全检测和规范代码,并且在运行期,就没有所谓的泛型,这是因为jvm对其进行了泛型擦出操作

测试代码:

public class Main {
	public static void main(String[] args) {
		List list = new ArrayList<>();
		List<Object> obj = new ArrayList<Object>();
		System.out.println(list.getClass()==obj.getClass());
	}
}

运行结果:true

这也就说明了在运行期,泛型擦出操作是存在的

Java反射:

java中提供的一套类库,通过这套类库
        -运行时动态获取类的信息
        -运行时动态调用构造函数创建对象
        -运行时动态访问(调用)对象的方法或属性
java反射实在程序运行时期所进行的操作,用来获取和操作类的信息(包括构造函数,属性和方法)

但是,如果使用反射对泛型进行操作会怎样呢?

测试代码:

import java.util.List;
import java.util.Map;

public class Demo {
	
	public void getList(List<Person> list){
		
	}
	
	public void getMap(Map<String,Person> map){

	}
}
class Person{}

测试类:

import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class Test {
	public static void main(String[] args) {
		try {
			
			Class<?> clazz = Class.forName("test.Demo");
			Method[] methods = clazz.getDeclaredMethods();
			for(Method m:methods){
				Type[] type = m.getGenericParameterTypes();//获取参数类型
				for(Type t:type){
					System.out.println(t);
				}
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

运行结果:

可以看到,程序打印出的方法中参数类型的信息,还打印出了他们泛型的信息

原因:

在周志明写的深入理解java虚拟机中有这样一段话:


Signature属性在JDK 1.5发布后增加到了Class文件规范之中,它是一个可选的定长属性,可以出现于类、属
性表和方法表结构的属性表中。在JDK 1.5中大幅增强了Java语言的语法,在此之后,任何类、接口、初始化方法
或成员的泛型签名如果包含了类型变量(Type Variables)或参数化类型(Parameterized Types),则Signature
属性会为它记录泛型签名信息。之所以要专门使用这样一个属性去记录泛型类型,是因为Java语言的泛型采用的是
擦除法实现的伪泛型,在字节码(Code属性)中,泛型信息编译(类型变量、参数化类型)之后都通通被擦除掉。
使用擦除法的好处是实现简单(主要修改Javac编译器,虚拟机内部只做了很少的改动)、非常容易实现
Backport,运行期也能够节省一些类型所占的内存空间。但坏处是运行期就无法像C#等有真泛型支持的语言那样,
将泛型类型与用户定义的普通类型同等对待,例如运行期做反射时无法获得到泛型信息。Signature属性就是为了
弥补这个缺陷而增设的,现在Java的反射API能够获取泛型类型,最终的数据来源也就是这个属性。

综上所述,泛型擦出的确存在,但是在JDK1.5之后,又出现了一个名为Signature的属性,用它来标识泛型的相关信息

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值