java反射:通过Method、Class发现泛型的本质

    在学习java集合的时候,泛型是个很重要的概念,它帮助我们防止了插入集合数据类型出错。在学习java反射的过程中,我们通过集合类对象的类类型进行操作,那么通过这种操作对集合泛型有什么不同?
    首先我们创建两个集合对象,其中一个带有泛型String,另一个不带有泛型,插入集合的元素类型不受限制

 ArrayList list=new ArrayList();
 ArrayList<String> list1=new ArrayList<String>();
     list1.add("hello");

    则我们现在可以向集合list中添加任意类型对象,而在list1中只能添加String类型的对象,如果我们向list1中加入Integer类型的数据对象,则在编译阶段会出现报错
    接下来我们通过类类型和Method来调用ArrayList类中的方法

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

输出结果为:
true
    则两个不同泛型的集合对象类型相同,这在我们看来是不合理的,为什么两个不同泛型的对象的类型会相等呢?
    这是因为,java的泛型是类型擦除的,即java的泛型在编译阶段是有效的,而在运行阶段会把类型擦除,上述的两个集合对象均变成ArrayList<>,此时比较其类型是相等的。而java的反射操作是在运行阶段进行的,绕过了相应的编译阶段而转换成了字节流,接下类我们来测试一下,java反射操作的执行阶段:

 Method m=c2.getMethod("add", Object.class);
     m.invoke(list1, 20);
     System.out.println(list1.size());
     System.out.println(list1);

    通过集合的类类型进行方法的调用,这时我们向list1中插入一个int类型的数据,按照泛型的要求,这个操作会在编译阶段发生错误,而运行结果显示:

2
[hello, 20]

    插入集合的操作成功进行,说明此时泛型已经被“擦除”,而反射操作在运行时期进行,由此我们可以得出结论:
    集合泛型在编译阶段有效,而在运行阶段被“擦除”

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值