通过反射了解泛型的本质

通过Class,Method来认识泛型的本质
我们知道Java中集合的泛型是防止错误输入的,例如ArrayList<String>list1=new ArrayList<String>();接下来如果再有list1.add(20);系统便提示错误,程序无法通过编译,以为list1的类型已被指定为String,那么我们看以下代码

Class c1=list.getClass();
Class c2=list1.getClass();
System.out.println(c1==c2);

此时系统输出的是却是true,未使用泛型的list和使用泛型指定唯一类型Stringlist1具有相同的类类型(getClass()方法返回类的类类型)吗??
原因在于——泛型只在编译阶段有效,编译完成后自动去泛型化,而反射操作都是编译之后的操作,下面我们举例加深理解。

package 反射与泛型;
import java.lang.reflect.Method;
import java.util.*;
public class Example {
       public static void main(String[] args) {
        ArrayList list=new ArrayList();

        ArrayList<String>list1=new ArrayList<String>();
        list1.add("hello");
        //list1.add(20);错误的,编译不通过
        Class c1=list.getClass();
        Class c2=list1.getClass();
        System.out.println(c1==c2);
        //反射的操作都是编译之后的操作
        //
        /*
         * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
         * Java中集合的泛型是防止错误输入的,只在编译阶段有效,绕过编译就无效了
         * 验证:我们可以通过方法的反射来操作,绕过编译
         * 
         */
        try {
            Method m=c2.getMethod("add", Object.class);
            m.invoke(list1, 20);//绕过编译操作就绕过了泛型
            System.out.println(list1.size());
        } catch (Exception e) {
            e.printStackTrace();
        } 

    }
}

这里写图片描述

很显然,我们成功地使用反射绕过了泛型为list1添加了一个int类型的元素20,说明绕过绕过编译操作也就绕过了泛型。

总结

此刻,我们对于泛型和反射有了一定的认识,但是编译过程到底是如何实现的,底层类的加载执行又有哪些细节,还有待于深入学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值