• 浅析Java反射机制


    一、基本概念

    动态获取类信息以及动态调用该对象的属性和方法的功能称之为 反射 。

    此处的 动态 指的是运行时获取, javac编译 -> 生成.class文件 -> 运行主类

    优点:

    1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。
    2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
    3. 反射是所有第三方框架的基础。

    缺点:

    1. 使用反射会有效率问题,会导致程序效率降低。
    2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。

    二、反射操作的核心类

    实现反射操作需要4个核心类,这些类都在 java.lang.reflect 包下

    2-1 Class

    1.在Java中获取一个类的class对象,有三种途径:

    1. // Ⅰ.直接通过类名.class获取class对象
    2. Class cls1 = Student.class;
    3. // Ⅱ.通过该类的任意实例化对象,调用getClass()方法
    4. Class cls2 = new Student().getClass();
    5. // Ⅲ.使用Class类提供的静态方法 Class.forName(“包名.类名”);
    6. Class cls3 = Class.forName("demo.Student");

    2.调用 class对象 的 newInstance() 方法产生 Student类 的实例

    1. // 默认调用该类的无参构造,当访问不到无参构造时,无法使用该方法
    2. Student stu = (Student) cls.newInstance();

    2-2 Constructor

    1.通过class 对象获取构造方法

    1. ① getConstructors() 只能获取当前类的 所有public 权限的构造方法
    2. Constructor[] constructors = cls.getConstructors();
    3. [public reflect.Student(java.lang.String,int,java.lang.String), public reflect.Student()]
    4. ② getDeclaredConstructors() 能获取当前类的 所有权限 的构造方法
    5. Constructor[] constructors1 = cls.getDeclaredConstructors();
    6. [public reflect.Student(java.lang.String,int,java.lang.String), reflect.Student(java.lang.String,int), private reflect.Student(java.lang.String), public reflect.Student()]
     
    

    ③ 拿到 一个无参构造 的constructor对象

    Constructor constructor = cls.getDeclaredConstructor();

    ④ 拿到 一个有参构造 的constructor对象

    1. Constructor constructor1 = cls.getDeclaredConstructor(String.class);
    2. Constructor constructor2 = cls.getDeclaredConstructor(String.class, Integer.class);
    3. Constructor constructor3 = cls.getDeclaredConstructor(String.class, Integer.class, String.class);

    2.当拿到特定的Constructor对象时,就可以通过该对象来实例化Student对象

    1. // 破坏封装,仅限当前JVM进程中的这个constructor1可用
    2. constructor1.setAccessible(true);
    3. Student stu = (Student) constructor1.newInstance();

    2-3 Method

    1. ① 获取该类的所有方法Method对象,可以拿到当前类以及其父类的 所有public权限 的方法
    2. Method[] methods = cls.getMethods();
    3. ② 可以拿到当前类的 所有权限 的方法,包括private权限
    4. Method[] methods1 = cls.getDeclaredMethods();
    5. ③ 拿到当前类的 某个方法 ,getDeclaredMethod(方法名称,方法的参数类型)
    6. Method staticMethod = cls.getDeclaredMethod("staticFunc", String.class);
     
    

    2-4 Field

    1. ① 可以拿到当前类以及其父类的 所有public的属性
    2. Field[] fields = cls.getFields();
    3. ② 可以拿到当前类的 所有权限的属性 ,包括private权限
    4. Field[] fields1 = cls.getDeclaredFields();
    5. ③ 可以拿到 指定属性
    6. Field field = cls.getDeclaredField("name");
     
    

    三、反射的应用

    3-1 通过反射调用方法

    1. // 第一步,获取 class 对象
    2. Class cls = new Demo().getClass();
    3. // cls.getDeclaredMethod(方法名称,方法的参数类型)
    4. Method staticMethod = cls.getDeclaredMethod("staticFunc", String.class);
    5. // 静态方法的调用不需要实例化对象
    6. // methodFunc.invoke(具体对象,方法参数);
    7. staticMethod.invoke(null, "abcde");
    8. Method methodFunc = cls.getDeclaredMethod("fun");
    9. // fun()方法是private的,需要破坏封装
    10. methodFunc.setAccessible(true);
    11. // fun()是成员方法,必须通过Student的对象来调用
    12. Student stu = (Student) cls.newInstance();
    13. // 开始调用方法
    14. // methodFunc.invoke(具体对象,方法参数);
    15. methodFunc.invoke(stu);

    通过反射来调用一个类的方法的过程:

    1. 先获取该类的class对象
    2. 通过getMethod或getDeclaredMethod获取这个方法的method反射对象
    3. 若该方法是一个成员方法,则需要产生该类的实例
    4. method.invoke(该类的实例, 方法的具体参数);

    3-2 通过反射获取/修改属性

    1. // 第一步,获取 class 对象
    2. Class cls = Class.forname("demo.Student");
    3. // 获取指定的属性
    4. Field field = cls.getDeclaredField("name");
    5. field.setAccessible(true); // 因为name是private修饰的属性
    6. // name是成员属性,所以需要Student的实例化对象
    7. Student stu = (Student) cls.newInstance();
    8. // 设置属性值:set(具体对象, 属性值);
    9. field.set(stu, "张三");
    10. // 获取属性值:通过具体的Student对象获取name属性
    11. System.out.println(field.get(stu));

    通过反射来获取一个类的属性的过程:

    1. 先获取该类的class对象
    2. 通过getField或getDeclaredField获取指定属性的Field对象
    3. 创建该类的实例(若该属性是一个成员属性)
    4. set(obj-具体操作的对象, 要设置的属性值); get(obj-具体操作的对象);

    总结:

    提示:这里对文章进行总结:

    以上就是今天的学习内容,本文是Java反射的学习,认识什么是反射,反射相关的类,以及反射的原理和过程。之后的学习内容将持续更新!!!

  • 相关阅读:
    mindspore-使用net(input)或者model.predict获取对应预测值,forward获取一次结果较慢
    混合牛奶 | 贪心算法 (USACO练习题)
    今天的码农女孩开始学习react的知识
    拒绝摆烂:我怎么从一个普通的弱电工人变成大厂网络工程师?
    Peoeasy机器人:原点无法重置问题
    国标EHOME视频平台EasyCVR视频融合平台助力地下停车场安全
    exoplayer的使用-4,手势,事件监听等
    Android焦点控制和键盘弹出
    全球首例:肾衰7年的他移植了一颗猪肾脏
    FPGA学习----Verilog HDL语法(1)
  • 原文地址:https://blog.csdn.net/guanshengg/article/details/126343118