反射(Reflection)

基本概念

​ 反射机制允许程序在执行期间借助于ReflectionAPI取得任何类的内部信息(成员变量、构造器、成员方法等),并操作对象的属性和方法。

​ 加载完类之后,在堆中就产生了一个Class类型的对象,包含了类的完整结构信息

Java反射机制可以完成

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时得到任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的成员变量和方法
  • 生成动态代理

反射机制的主要类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FY3k9lTE-1647694879032)(D:\Typora\Java学习\image-20220318183709637.png)]

代码实现

  public static void main(String[] args) throws Exception {
        //创建Properties对象
        Properties properties = new Properties();
        //输入流读取配置文件
        properties.load(new BufferedReader(new FileReader("D:\\JavaProject\\JavaSE\\practice01\\src\\re.properties")));
        String classPath = properties.getProperty("name");
        String methodName = properties.getProperty("method");
        //使用反射机制加载类
        Class cls = Class.forName(classPath);
        //通过加载的类获取对象实例
        Object o = cls.newInstance();
        System.out.println("运行类型为" + o.getClass());
        Method method = cls.getMethod(methodName);
        System.out.println("===============================");
        //调用对象的方法:方法.invoke(对象)
        method.invoke(o);
        //getField不能得到私有的字段
        Field nameField = cls.getField("age");
        //获取属性值:成员变量对象.get(对象)
        System.out.println(nameField.get(o));
        //反射机制获取类的无参构造器
        Constructor constructor = cls.getConstructor();
        System.out.println(constructor);
        //反射机制获取类的有参构造器,传输参数为构造器指定参数的类对象
        Constructor constructor1 = cls.getConstructor(String.class);
        System.out.println(constructor1);


    }

反射的优点和缺点

优点:可以动态地创建和使用对象,框架的底层核心,使用灵活。

缺点:使用反射基本是解释执行,对执行速度有影响,比正常创建类访问 要慢

method.setAccessible(true);
//在反射调用方法时,取消检查访问,可提高一定执行效率 

Class类

  • class类也是一个类,也继承自Object类
  • Class类对象不是new出来的,而是通过ClassLoder类的loadClass( )创建
  • 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
  • 每个对象实例都会记得自己是由哪个Class实例生成的
  • 通过Class对象可以完整得到一个类的完整结构
  • Class对象是存放在堆中的
  • 类加载时同时为产生类的字节码二进制数据,存放在方法区,有的地方称为类的元数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IH9JHYjf-1647694879034)(D:\Typora\Java学习\image-20220318214801472.png)]

Class类常用方法

        String classAllPath = "reflection.Car";
        Class<?> cls = Class.forName(classAllPath);
        //显示是哪个类的Class对象 class reflection.Car
        System.out.println(cls);
        //输出Class对象的运行类型 class java.lang.Class
        System.out.println(cls.getClass());
        //输出该类所在的包名 reflection
        System.out.println(cls.getPackage().getName());
        //输出全类名 reflection.Car
        System.out.println(cls.getName());
        //通过Class对象创建Car对象实例
        Car car = (Car) cls.newInstance();
        //通过toString方法,输出car的属性
        System.out.println(car);
        //通过反射获取Car中的属性对象brand public       java.lang.String reflection.Car.brand
        Field brand = cls.getField("brand");
        System.out.println(brand);
        //通过反射获取属性的值 奔驰
        System.out.println(brand.get(car));
        //通过反射给对象属性赋值 宝马
        brand.set(car, "宝马");
        System.out.println(brand.get(car));
        //获取所有属性字段的名称 brand price color
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.print(field.getName());
        }
    }

获取Class类对象的六种方式

​ 已知类的全类名,且该类在类路径下,可通过Class类的静态方法**forName(全类名)**获取,多用于配置文件,读取类全路径,加载类

 Class cls1 = Class.forName("reflection.Car");

​ 已知具体的类,通过类的class获取,多用于参数传递,比如反射得到对应的构造器

      Class<Car> cls2 = Car.class;

​ 已知某个类的实例,调用该实例的getClass方法获取Class对象,多用于通过创建好的对象,获取Class对象

        Car car = new Car();
        Class<Car> cls3 = car.getClass();

​ 基本数据类型对应的包装类可通过 .TYPE得到Class对象

  Class<Integer> IntegerClass = Integer.TYPE;

哪些类型有Class对象

  1. 外部类,成员内部类,静态内部类,局部内部类,匿名内部类
  2. interface:接口
  3. 数组
  4. enum:枚举
  5. annotation:注解
  6. 基本数据类型
  7. void

类加载

反射机制是Java实现动态语言的关键,也就是通过反射实现类动态加载

静态加载:编译时加载相关的类,如果找不到该类则报错,依赖性太强

动态加载:运行时加载需要的类,如果运行时不使用该类,即使不存在该类也不会报错,依赖性降低

类加载时机

创建对象时(new)静态加载

子类被加载时,父类也加载 静态加载

调用类中的静态成员时 静态加载

通过反射机制 动态加载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值