• 反射详细说明


    反射概述

    反射是指对于任何一个Class类,在"运行的时候"都可以直接得到这个类全部成分。

    在运行时,可以直接得到这个类的构造器对象:Constructor。

    在运行时,可以直接得到这个类的成员变量对象:Field。

    在运行时,可以直接得到这个类的成员方法对象:Method。

    这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。

    反射获取类对象

    三种方式获取类对象

     

    反射获取构造器对象并使用

    Constructor[] getConstructors​()返回所有构造器对象的数组(只能拿public的)
    Constructor[] getDeclaredConstructors​()返回所有构造器对象的数组,存在就能拿到
    Constructor getConstructor​(Class... parameterTypes)返回单个构造器对象(只能拿public的)
    Constructor getDeclaredConstructor​(Class... parameterTypes)返回单个构造器对象,存在就能拿到

    Constructor类中用于创建对象的方法 

    T newInstance​(Object... initargs)根据指定的构造器创建对象
    public void  setAccessible(boolean flag)对于非public构造器需要设置为true,表示取消访问检查,进行暴力反射

    反射获取成员变量对象并使用

    Field[] getFields​()返回所有成员变量对象的数组(只能拿public的)
    Field[] getDeclaredFields​()返回所有成员变量对象的数组,存在就能拿到
    Field getField​(String name)返回单个成员变量对象(只能拿public的)
    Field getDeclaredField​(String name)返回单个成员变量对象,存在就能拿到

    使用成员变量

    void set​(Object obj, Object value)赋值
    Object get​(Object obj)获取值
    public void  setAccessible(boolean flag)对于非public成员变量需要设置为true,表示取消访问检查,进行暴力反射

    反射获取方法对象并使用

    Method[] getMethods​()返回所有成员方法对象的数组(只能拿public的)
    Method[] getDeclaredMethods​()返回所有成员方法对象的数组,存在就能拿到
    Method getMethod​(String name, Class... parameterTypes)返回单个成员方法对象(只能拿public的)
    Method getDeclaredMethod​(String name, Class... parameterTypes)返回单个成员方法对象,存在就能拿到

     使用Method对象

    Object invoke​(Object obj, Object... args)

    参数一:用obj对象调用该方法

    参数二:调用方法的传递的参数(如果没有就不写)

    返回值:方法的返回值(如果没有就不写)

    public void  setAccessible(boolean flag)对于非public成员方法对象需要设置为true,表示取消访问检查,进行暴力反射

    反射的作用-绕过编译阶段为集合添加数据

     如下代码在编译阶段是通不过的:

    1. ArrayList list = new ArrayList<>();
    2. list.add(100);
    3. list.add(“黑马"); // 报错
    4. list.add(99);

     而泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段的时候,其真实类型都是ArrayList了,泛型相当于被擦除了。那么我们就可以用反射技术为该集合添加字符串,因为反射技术就是在运行阶段运用的。如下所示:

    1. ArrayList list = new ArrayList<>();
    2. list.add(100);
    3. //list.add("黑马"); // 报错
    4. list.add(99);
    5. Classextends ArrayList> listClass = list.getClass();
    6. Method add = listClass.getDeclaredMethod("add", Object.class);
    7. add.invoke(list,"heima");
    8. System.out.println(list);

    反射的作用-通用框架的底层原理

    需求:给你任意一个对象,在不清楚对象字段的情况可以,可以把对象的字段名称和对应值存储到文件中去。

     分析

    定义一个方法,可以接收任意类的对象。

    每次收到一个对象后,需要解析这个对象的全部成员变量名称。

    这个对象可能是任意的,那么怎么样才可以知道这个对象的全部成员变量名称呢?

    使用反射获取对象的Class类对象,然后获取全部成员变量信息。

    遍历成员变量信息,然后提取本成员变量在对象中的具体值

    存入成员变量名称和值到文件中去即可。

    代码:

    1. public static void save(Object obj){
    2. try (
    3. PrintStream ps = new PrintStream(
    4. new FileOutputStream("E:\\data.txt",true));
    5. ){
    6. Class objClass = obj.getClass();
    7. Field[] fields = objClass.getDeclaredFields();
    8. ps.println("==="+objClass.getSimpleName()+"===");
    9. for (Field field : fields) {
    10. field.setAccessible(true);
    11. String name = field.getName();
    12. String value = field.get(obj)+"";
    13. ps.println(name + "="+value);
    14. }
    15. } catch (Exception e) {
    16. throw new RuntimeException(e);
    17. }
    18. }

    总结

    反射的作用?

    可以在运行时得到一个类的全部成分然后操作。

    可以破坏封装性。(很突出)

    也可以破坏泛型的约束性。(很突出)

    更重要的用途是适合:做Java高级框架

    基本上主流框架都会基于反射设计一些通用技术功能。

  • 相关阅读:
    2741. 特别的排列 Medium
    鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统
    6.28U-Net深度学习基准模型特点与应用
    【C++】C++入门
    Json解析流程
    Vue源码探秘(一)——Vue-Router原理实现
    山西佳诺德:短视频拍摄的知识有哪些
    Spring 中有哪些感知接口
    MSTP理论讲解
    thinkphp执行复杂存储过程,有时候成功,有时候失败的解决办法
  • 原文地址:https://blog.csdn.net/daqi1983/article/details/133206160