泛型擦除-java基础入门必备

泛型擦除:

阅读下面之前先理解泛型,这样有利于加强理解。

1.泛型擦除概念:在JVM中一切关于对T的传参都不再有效,都将被向上转译成相应的其他类型,何为向上转译,且听我细细道来:可以代表任意类类型,但任意类类型的直接父类都是Object,而<T extends 类类型>的直接父类是<T extends 类类型>中的类类型,这就是所谓的向上转译
2.泛型擦除规则:
对于没有继承的T(其他字母代替也可以,这没有特别要求),即擦除后转译为Object类型,但如果指定了上限,即<T extends 类类型>转译为类类型,例如则转译为Integer类型

3.下面我们来通过demo来理解泛型擦除:

System.out.println("------------------------No.6_1泛型类型擦除例子 :--------------------------------------------");
		List<String> l1 = new ArrayList<String>();
		List<Integer> l2 = new ArrayList<Integer>();
		System.out.println("泛型擦除 : "+(l1.getClass()==l2.getClass()));

测试结果:
在这里插入图片描述
分析:l1对应的类是String,l2对应的类是Integer,答案为什么是true?原因是:List和List l2在JVM中都是List.class,也就是说List和List l2都没了,用专业术语来讲是类型擦除,至于List和List l2是怎么转换成List.class(泛型转译)的呢?这时我们就可以使用反射机制来动态获取类信息了:
3_1.首先先获取类信息:

Et<String> etTest12 = new Et<String>("字符串类型");
		Class etTest12_1 = etTest12.getClass();
		System.out.println("Et class is : "+etTest12_1.getName());	

在这里插入图片描述
3_2.再利用反射获取属性:

Field[] fi = etTest12_1.getDeclaredFields();
		for(Field fp:fi) {
			System.out.println("Field name : "+fp.getName()+" type :"+fp.getType().getName());	
		}

看吧,属性key的类型是Object,与我们上面的规则不矛盾,perfect,
在这里插入图片描述
3_3.然后我们将类的参数改为 :public class Et <T extends String> 然后重复执行3_2demo,结果如下:很完美,跟规则一模一样,

在这里插入图片描述
3_4.既然我们能用反射获取属性的类型,我们也能够以此来获取方法中参数和方法的类型,如下:

Method[] me  =  etTest12_1.getDeclaredMethods(); 
		for(Method mp:me) {
			System.out.println("Method : "+mp.toString());	
		}

看吧,完全在意料之中,方法类型java.lang.Object,参数类型也是java.lang.Object。
在这里插入图片描述
来到这里,我们不仅明白了泛型擦除的真谛,也明白了反射能够对擦除的属性和方法进行操作,基于这一点,我们能够利用固定传参后的类进行不同数据类型的值的存取。如下:List<Integer> l3 = new ArrayList<Integer>();已经固定是String类型了,但通过反射调用擦除的add()方法实现了对字符串,双精度等等类型的值的存储。

System.out.println("------------------------No.6_2利用泛型类型擦除和反射绕过泛型限制的例子 :--------------------------------------------");
		List<Integer> l3 = new ArrayList<Integer>();
	    l3.add(123);
	    try {
	    //注意方法名和参数类型(Object.class)
			Method method = l3.getClass().getDeclaredMethod("add", Object.class);
			try {
			//调用add()方法
				method.invoke(l3, "test");
				method.invoke(l3, 1024.857);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	       for(Object l3_1:l3) {
		System.out.println(l3_1);
	     }
	}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值