Java反射(learning)

Java - reflection

Java反射(Reflection)是Java语言的一个特性,它允许程序在运行时检查和修改内部类的行为。通过反射,可以获取类的构造器、方法、字段等成员的信息,并且可以动态地创建对象、调用方法、访问和修改字段。

Java反射主要涉及到以下几个类:

  • java.lang.Class:代表一个类,每个类都有一个与之对应的Class对象。可以通过.class语法或Class.forName()等方法获取一个类的Class对象。
  • java.lang.reflect.Constructor:代表一个类的构造器,通过它可以动态创建类的实例。
  • java.lang.reflect.Method:代表一个类的方法,通过它可以动态调用类的方法。
  • java.lang.reflect.Field:代表一个类的字段,通过它可以动态访问和修改类的字段。

0. 实体类Car

package org.spring6Demo.reflect;

public class Car {
    private String brand;
    private String color;
    private int price;

    // no param constructor
    public Car() {
    }

    // private constructor
    private Car(String brand, int price) {
        this.brand = brand;
        this.price = price;
    }

    // public params_constructor
    public Car(String brand, String color, int price) {
        this.brand = brand;
        this.color = color;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    private void run() {
        System.out.println("private method run()");
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }
}

1. 获取类的Class对象

    @Test
    public void test01() throws Exception {
        // 类名.class
        Class<Car> carClass1 = Car.class;
        // 对象.getClass()
        Class<? extends Car> carClass2 = new Car().getClass();
        // Class.forName(全路径)
        Class<?> carClass3 = Class.forName("org.spring6Demo.reflect.Car");
        // 实例化
        Car car = (Car) carClass3.getDeclaredConstructor().newInstance(); // 默认无参构造
        System.out.println(car);
    }

2. 获取构造函数

    // 获取构造方法
    @Test
    public void test02() throws Exception {
        Class<Car> carClass = Car.class;

        // 获取所有构造方法
        Constructor<?>[] constructors1 = carClass.getConstructors(); // 仅能获取到public constructor
        for (Constructor<?> c : constructors1) {
            System.out.println(c.getName() + "  Modifier:" + modifiers_to_String(c.getModifiers()) + "  params:" + Arrays.toString(paramsClass_to_String(c.getParameterTypes())));
        }  // org.spring6Demo.reflect.Car  Modifier:public  params:[String, String, int]
        System.out.println("=============================================");

        Constructor<?>[] constructors2 = carClass.getDeclaredConstructors(); // 可获取到所有声明了的constructor
        for (Constructor<?> c : constructors2) {
            System.out.println(c.getName() + "  Modifier:" + modifiers_to_String(c.getModifiers()) + "  params:" + Arrays.toString(paramsClass_to_String(c.getParameterTypes())));
        } // org.spring6Demo.reflect.Car  Modifier:private  params:[String, int]
        System.out.println("=============================================");

        // 指定使用有参构造实例化
        // public constructor
        Constructor<Car> constructor1 = carClass.getConstructor(String.class, String.class, int.class);
        Car car1 = constructor1.newInstance("BWM", "white", 500000);
        System.out.println(car1);
        System.out.println("=============================================");
        // private constructor
        Constructor<Car> constructor2 = carClass.getDeclaredConstructor(String.class, int.class);
        constructor2.setAccessible(true); // 设置可以访问私有构造
        Car car2 = constructor2.newInstance("Benz", 450000);
        System.out.println(car2);
    }

3. 获取属性

    @Test
    public void test03() throws Exception {
        Class<?> carClass = Car.class;

        // 获取所有声明了的属性(包括私有属性)
        // getFields()仅获取所有public属性
        Field[] fields = carClass.getDeclaredFields();
        for (Field f : fields) {
            System.out.println("Attribute Name:" + f.getName() + "   Type:" + f.getType().getSimpleName() + "   Modifier:" + modifiers_to_String(f.getModifiers()));
        } // Attribute Name:brand   Type:String   Modifier:private

        // 为属性设置值
        Car car = (Car) carClass.getDeclaredConstructor().newInstance();
        for (Field f : fields) {
            if (Modifier.isPrivate(f.getModifiers())) f.setAccessible(true);
            if (f.getName().equals("brand")) f.set(car, "BWM");
            if (f.getName().equals("color")) f.set(car, "white");
            if (f.getName().equals("price")) f.set(car, 500000);
        }
        System.out.println(car);
    }

4. 获取方法

    @Test
    public void test04() throws Exception {
        Class<?> carClass = Car.class;
        Car car = (Car) carClass.getDeclaredConstructor().newInstance();

        // 获取所有public method(包括所有public的内置方法:如equals,hashCode...)
        Method[] methods_public = carClass.getMethods();
        for (Method m : methods_public) {
            System.out.println("Method Name:" + m.getName() + "   Return Type:" + m.getReturnType().getSimpleName() + "   Modifier:" + modifiers_to_String(m.getModifiers()) + "   params:" + Arrays.toString(paramsClass_to_String(m.getParameterTypes())));
        } // Method Name:toString   Return Type:String   Modifier:public   params:[]
        System.out.println("=============================================");
        // 执行 public String toString()
        for (Method m : methods_public) {
            if (m.getName().equals("toString")) {
                System.out.println((String) m.invoke(car));
            }
        }
        System.out.println("=============================================");

        // 获取所有显式声明了的method(包括private方法,不包含隐式的内置方法)
        Method[] methods_all = carClass.getDeclaredMethods();
        for (Method m : methods_all) {
            System.out.println("Method Name:" + m.getName() + "   Return Type:" + m.getReturnType().getSimpleName() + "   Modifier:" + modifiers_to_String(m.getModifiers()) + "   params:" + Arrays.toString(paramsClass_to_String(m.getParameterTypes())));
        } // Method Name:run   Return Type:void   Modifier:private   params:[]
        System.out.println("=============================================");
        // 执行 private void run()
        for (Method m : methods_all) {
            if (m.getName().equals("run")) {
                m.setAccessible(true);
                m.invoke(car);
            }
        }
    }

5. Util

    private String modifiers_to_String(int modifiers) {
        if (Modifier.isPublic(modifiers)) return "public";
        if (Modifier.isPrivate(modifiers)) return "private";
        if (Modifier.isProtected(modifiers)) return "protected";
        return "";
    }

    private String[] paramsClass_to_String(Class<?>[] paramsClass) {
        String[] types = new String[paramsClass.length];
        for (int i = 0; i < paramsClass.length; i++) {
            types[i] = paramsClass[i].getSimpleName();
        }
        return types;
    }
posted @   CodingSaltFish  阅读(7)  评论(0)    收藏  举报
点击右上角即可分享
微信分享提示