反射记录日记

一、什么是反射

反射是可以在运行是获取目标类的所有信息,包括:构造函数、方法、成员变量、包括其中的返回类型、访问修饰符等等...

二、怎么使用反射

1、获取反射对象

​
package org.reflect;

/**
 * @description: 反射
 */
public class TestCar {

    //1、获取class对象的方式
    @Test
    public void getClassObject(){

        //创建实例对象
        Car car = new Car();
        // ① 实例对象.getClass()
        Class<? extends Car> aClass1 = car.getClass();

        // ② Class.format("类全路径")
        try {
            Class<?> aClass2 = Class.forName("org.reflect.Car");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        //③ 类名.Class
        Class<Car> carClass = Car.class;
    }

}

2、获取构造方法

package org.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;

/**
 * @description: 反射
 */
public class TestCar {

    //2、获取构造方法
    @Test
    public void getConstructorObject(){
        // ② Class.format("类全路径")
        try {
            Class<?> aClass2 = Class.forName("org.reflect.Car");

            //获取对应的 public 的构造器
            Constructor<?> car1 = aClass2.getConstructor();
            Constructor<?> car2 = aClass2.getConstructor(String.class, int.class, String.class);
            //private 和 public 都可以获取
            Constructor<?> car3 = aClass2.getDeclaredConstructor(String.class);

            //创建实例
            Car car = (Car) car1.newInstance();


        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

3、获取方法

package org.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * @description: 反射
 */
public class TestCar {


    //3、获取方法
    @Test
    public void getMeObject(){
        // ② Class.format("类全路径")
        try {
            Class<?> aClass2 = Class.forName("org.reflect.Car");

            //① 创建实例
            Object o = aClass2.newInstance();

            //② 获取方法
            //②-1获取单个方法 public 类型
            Method run = aClass2.getMethod("runPublic");
            //②-2获取所有 public 类型的方法
            Method[] methods = aClass2.getMethods();
            System.out.print("所有public方法:");
            for (Method method:methods){
                System.out.print(method.getName()+",");
            }
            System.out.println("");
            //运行方法
            run.invoke(o);

            //②-3获取单个方法,支持 private 和 public
            Method runPrivate = aClass2.getDeclaredMethod("runPrivate");
            //操作private方法
            runPrivate.setAccessible(true);
            runPrivate.invoke(o);

            //②-4获取所有方法,支持获取 private 和 public
            Method[] declaredMethods = aClass2.getDeclaredMethods();
            System.out.print("所有方法:");
            for (Method method:declaredMethods){
                System.out.print(method.getName()+",");
            }
            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

 4、获取属性

package org.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @description: 反射
 */
public class TestCar {

    
      //4、获取属性
    @Test
    public void getAttr(){
        try {
            //获取反射对象
            Class<?> aClass2 = Class.forName("org.reflect.Car");

            //获取 public 有参构造器
            Constructor<?> constructor = aClass2.getConstructor( String.class);
            Car o = (Car)constructor.newInstance( "黑色");
            //获取单个 public 属性
            Field price = aClass2.getField("price");
            price.set(o,"10.00");
            System.out.println("修改后的price:"+o.price);

            //获取所有 public 属性
            Field[] fields = aClass2.getFields();
            System.out.print("------所有public属性名称:");
            for (Field f:fields) {
                System.out.print(f.getName()+",");
            }
            System.out.println();
            //获取所有属性 包括private
            Field[] fields1 = aClass2.getDeclaredFields();
            //获取任意单个属性,可private、public...
//            Field name = aClass2.getDeclaredField("name");

            System.out.print("-----所有属性名称:");
            for (Field f:fields1) {
                System.out.print(f.getName()+",");
                if("price".equals(f.getName())){
                    f.set(o,"12.44");
                }

                if("name".equals(f.getName())){
                    //设置允许设置私有属性
                    f.setAccessible(true);
                    f.set(o,"测试私有属性设置");
                }
            }
            System.out.println("修改后的颜色:"+o.price+",名称:"+ o.getName());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

测试类

package org.reflect;


/**
 * @description: 反射测试类
 */
public class Car {


    //属性
    private String name;

    private int age;

    private String color;

    public String price;

    //无参构造
    public Car() {
        System.out.println("无参构造......");
    }

    private Car(int age) {
        System.out.println("private构造......");
    }

    public Car(String color) {
        System.out.println("color构造......"+color);
    }
    //有参构造
    public Car(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造......");
    }

    //get、 set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }


    public void runPublic(){
        System.out.println("public方法Run......" +
                "");
    }

    private void runPrivate(){
        System.out.println("private方法Run......");
    }

}

三、反射应用场景

  • 框架设计
  • 动态代理
  • 配置与注解处理
  • 单元测试
  • 配置与注解处理

四、反射优缺点

优点:

  • 灵活性和可扩展性
  • 框架和库的支持

缺缺:

  • 性能问题
  • 安全风险

参考文章

Java中的反射机制是什么?它在实际开发中有哪些应用场景?-CSDN博客

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值