java反射--通过反射了解集合泛型的本质

通过Class,Method来认识泛型的本质

package com.reflect;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class MethodDemo2 {

    public static void main(String[] args) throws Exception
    {
        ArrayList list=new ArrayList();
        ArrayList<String> list1=new ArrayList<String>();
        
        list1.add("hello");
    //  list1.add(10);//会因为10不是String类型而出错
        Class c1=list.getClass();
        Class c2=list1.getClass();
        System.out.println(c1==c2);
        
        //反射的操作都是编译之后的操作
        
        /*
         * C1==C2结果返回true,说明编译后集合的泛型是去泛型化的
         * Java中,集合的泛型,是防止错误输入的,只在编译阶段有效
         * 绕过编译就无效了
         * 验证:我们可以通过方法的反射来操作,绕过编译
         * */
        Method m=c1.getMethod("add", Object.class);
        m.invoke(list1, 1);
        System.out.println(list1.size());
        System.out.println(list1);
        //此时不能用这种方式遍历了,因为之前已经插入了int类型的,这样会转化为String类型,会转换错误
        for(String str:list1)
        {
            System.out.println(str);
        }
    }
} 

运行结果:

 

分析上诉结果:

1,list和list1都能add加入集合String类型变量,但是list1由于使用了泛型,所以限定只能加入String类型的,而不能加入Int类型的,但是list没有使用泛型,所以

可以加入任意类型变量。使用泛型的作用就是为了防止输入了错误类型的变量。

2,list1不能加入int类型的变量,是因为编译时候,进行了校验,但是反射是在编译后进行的操作,因此可以绕过编译

3,因为c1==c2,说明list1和list是同一种类类型,都是ArrayList类的类类型。

4,因为泛型绕过了编译,所以使用泛型调用方法的时候,即使使用的是list1集合对象,依然可以插入int类型的变量。

5,list1对象插入了int类型的变量后,不能使用foreach方式输出了,因为此时是通过编译的方式,需要进行int到String类型的转型,显然会报错。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值