Java-反射机制总结

本文介绍了Java反射机制的概念,包括其在运行时动态获取和操作类信息的能力。详细讲解了反射原理、相关类的使用(如Class、Method、Field和Constructor),并探讨了如何处理私有变量和反射效率的问题。

Java-反射机制总结

一、反射机制

1.1 概念

反射机制是指在运行时动态地获取和操作类的信息、对象的属性和方法的能力。通过反射,可以在编译时无法确定的情况下,通过获取类的元数据信息,实现对类、对象、方法的检查、调用和操作。
  • 理解:

    • 反射机制允许:程序在执行期间借助于Reflection API取得任何类的内部信息(比如成员变量,构造方法,成员方法等的),并且能够操作对象的属性及方法。【在 设计模式 和 框架的底层 常用】

    • 类加载完后,在堆中产生一个Class类型的对象(一个类仅产生一个Class对象),这个Class类型的对象包含了类的完整结构信息。

    • 通过这个Class类型的对象,可以得到类的结构以及各种类的信息,因此,Class对象就像一面镜子,透过镜子可以看到类的结构,所以形象地成为反射。

1.2 反射机制原理图

  • 回顾Java程序运行过程:

    • 1.编码:编写源代码(.java文件)
    • 2.编译:通过编译器(javac)编译成字节码(.class文件)
    • 3.类加载器加载:Java虚拟机(JVM)的类加载器将字节码文件(.class)加载到内存中;
    • 4.字节码验证:如结构,语义,类型等验证;
    • 5.执行:Java虚拟机解释字节码指令进行执行;
  • 以"反射机制引入"中的需求为例,绘制反射机制原理图如下:

反射机制原理图

二、反射机制相关的类

  • 主要的类如下:
类名所在包名描述
Classjava.lang.Class代表一个类,Class对象表示某个类加载后在堆中的对象
Methodjava.lang.reflection.Method代表类的方法
Fieldjava.lang.reflect.Field代表类的成员变量
Constructorjava.lang.reflect.Constructor代表类的构造方法

2.1 相关类的用法

  • 通过反射获取类的成员变量:

    • 自定义的Cat类
    /**
     * @author: sea
     * @date: 2023/5/23 16:33
     */
    public class Cat {
        private String name;
        public int age = 10;
        public void hi(){
            System.out.println("hihihi");
        }
    
        public void cry(){
            System.out.println("miamiamia");
        }
    }
    
    • 用法:
    /**
     * @author: sea
     * @date: 2023/5/29 09:22
     */
    public class Reflection_02_Field_Constructor {
      public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    
            String filePath = "./hsp_ch23/re.properties";
            Properties properties = new Properties();
            properties.load(new FileReader(filePath));
            String classFullPath = properties.getProperty("classfullpath");
            String method = properties.getProperty("method");
            //可以从文件中读取到 类的路径 和 方法名称,但是如果不使用反射机制的话,无法通过路径创建类的对象
            System.out.println("classfullpath=" + classFullPath + "\n" + "method=" + method);
    
            //(1) 通过 类的路径 加载 类,返回的是Class类型的对象aClass
            Class aClass = Class.forName(classFullPath);
    
            //(2) 通过 aClass 得到 加载的类(hsp_ch23.Reflection_.Cat)的对象实例
            Object o = aClass.newInstance();
            System.out.println("对象实例 o 的运行类型:" + aClass.newInstance().getClass());
          
          	//(3) 通过 aClass 可以获取到 加载的类(hsp_ch23.Reflection_.Cat)中名称为 读取到的method值 的方法对象(Method类的对象)
            // 即:在反射中,方法也视为一个对象
            Method method1 = aClass.getMethod(method);
    
            //(4) 通过 method1 来实现方法的调用
            method1.invoke(o);//此处,有点绕,传统方式:通过 对象示例 调用 类的方法【o.method1()】。 此处:方法.invoke(对象);
            
          
            //获取类的成员变量(Field对象)
            Field name = aClass.getField("name");
            System.out.println(name.get(o));// ==> o.name
          
          	Field age = aClass.getField("age");
            System.out.println(age.get(o));
          
            //获取构造器
            // (1)无参构造器
            Constructor constructor1 = aClass.getConstructor();
            System.out.println(constructor1);
            // (2)带参构造器
            Constructor constructor2 = aClass.getConstructor(String.class);
            System.out.println(constructor2);
            
        }
    }
    
    • 获取成员变量name时会报错,原因:name字段为私有成员变量,不能获取类的私有变量;、
      • 通过setAccessible()方法,传入true,使得可以通过反射来操作私有变量;
  • 反射机制相对于传统方式效率比较低,原因:反射机制涉及到一些权限检查等步骤。

2.2 哪些类型有Class对象

  • 如下类型有Class对象:
    • 外部类
    • 内部类(局部内部类、匿名内部类、成员内部类、静态内部类)
    • 接口:Interface
    • 数组:[]、[][]
    • 枚举类型:Enum
    • 注解:Annotation
    • 基本数据类型
    • void
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SEA-365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值