ismohney-and-curlie

反射的作用之动态对实例对象进行操作

    前提:我认为,反射概念在JavaSE内容中算是一个比较绕的知识点,反射本身好理解,但实际运用起来总会让人感觉好像又不是很对;对于反射的学习,我是先学具体使用再了解的作用,对于反射的作用之一,在这里做个笔记。

任务需求:对被Integer泛型约束的List集合,添加其他类型的元素

  一、必备知识

1、反射机制概念:对任何一个class类,在其运行时,都可以直接取得该Class对象和其全部成分;反射认为类中的每个成分都是单独的对象(符合Java的‘一切皆对象’概念),支持动态获取类信息以及动态调用类成分。

2、反射的“动态”:指越过编译阶段,可以直接对运行时Runtime阶段产生效果。

3、泛型:JDK5引入的一种特性,作用是在编译阶段约束数据类型并检查,只支持引用类型。

4、当泛型数据被编译成Class对象进入运行阶段,其真实类型取的是大范围类型,泛型被擦去。

5、泛型标识和通配符:包括T、E、K、V等,和?;其实二者对代码的作用是一样的,区别只是给程序员一个提示,不同字母有对应的提示意义;后者相较更代表一切类型,当无法确定类型时使用;但是二者依然还是作符号作用,对应的类是Object。

6、在对Class具体成分进行操作时,要有实例对象,指定实例对象(成分不可能脱离实例单独存在,比如-- 我的身高体重,不可能脱离我实际存在)。

7、因为反射作用于运行阶段,所以报错只在运行时才会出现,并且报错提示也比较不友好哈。

  二、操作

  · 明了《一》的7点内容,操作步骤是简单的,重在理解 !具体代码如下:

1、直接添加非Integer内容 --- 【报错】

 //1、创建list集合实例
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
//        list.add("aaa"); 报错

2、注意取到的Method add的第二个参数,'Object.class',作用(相当于反射的泛型,填了什么类型,通过反射添加就是什么类型,否则在运行阶段也会报错);要确保可以不止add一种类型数据,就要传参Object类(invoke传参受其限制)。

//2、使用运行阶段获取Class对象 方法
        Class c = list.getClass();
        //3、取Method对象(给集合添加数据的方法add)
        //add方法实际上的参数类型是不限的,所以使用泛型约束,确切定位时可以用Object类型,不影响使用
        Method add = c.getDeclaredMethod("add", Object.class);
        boolean flag = (boolean) add.invoke(list,"aaa");
        System.out.println(list);

【触发方法的传参和约定参数类型不一致,报错】

5、为什么泛型只作用于编译阶段(一、4)

 

4、查看运行结果

    三、总结

  总结就是,要分清楚实例和类的区别,实例的成员的修改,类成员的获取。

 

posted on 2023-06-03 17:28  ooyls  阅读(10)  评论(0编辑  收藏  举报

导航