Java(二)反射

105 阅读2分钟

反射是指在 程序运行时 访问、检测和修改类属性和方法。

一、反射API

Java 类成员包括:属性字段、构造方法、方法,反射 API 也和这些类成员相关:

  • Class:正在运行的 Java 应用程序中的类实例。
  • Constructor:提供有关类的构造方法的信息以及对它的动态访问权限。
  • Field:提供有关类的属性的信息,以及对它的动态访问权限。
  • Method:提供有关类的方法的信息,包括抽象方法。
  • Object:所有Java类的父类。

二、获取反射类对象

public class Reflection {
    
    public static void main(String[] args) throws ClassNotFoundException {
        // 方法一:通过类全称获取Class对象
        Class class1 = Class.forName("java.lang.String");
        System.out.println("class1 is: " + class1);
        // 方法二:通过类的class属性获取Class对象
        Class class2 = String.class;
        System.out.println("class2 is: " + class2);
        // 方法三:通过类实例对象的getClass()方法获取Class对象
        Class class3 = "".getClass();
        System.out.println("class3 is: " + class3);
        System.out.println(class1 == class2 && class2 == class3);
    }
}

运行结果

class1 is: class java.lang.String
class2 is: class java.lang.String
class3 is: class java.lang.String
true

三、获取属性

import java.lang.reflect.Field;

public class Reflection {

    public static double property0;

    private String property1;

    public int property2;

    public static void main(String[] args) {
        // 获取所有声明的属性
        Field[] declaredFields = Reflection.class.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println("Declared field: " + field);
        }
        // 获取所有公有属性
        Field[] fields = Reflection.class.getFields();
        for (Field field : fields) {
            System.out.println("Field: " + field);
        }
    }
}

运行结果

Declared field: public static double Reflection.property0
Declared field: private java.lang.String Reflection.property1
Declared field: public int Reflection.property2
Field: public static double Reflection.property0
Field: public int Reflection.property2

四、获取构造方法

import java.lang.reflect.Constructor;

public class Reflection {

    public Reflection() {
        System.out.println("Public Constructor");
    }

    private Reflection(String param) {
        System.out.println("Private Constructor");
    }

    public static void main(String[] args) {
        // 获取所有声明的构造方法
        Constructor[] declaredConstructors = Reflection.class.getDeclaredConstructors();
        for (Constructor constructor : declaredConstructors) {
            System.out.println("Declared constructor: " + constructor);
        }
        // 获取所有公有的构造方法
        Constructor[] constructors = Reflection.class.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("Constructor: " + constructor);
        }
    }
}

运行结果

Declared constructor: public Reflection()
Declared constructor: private Reflection(java.lang.String)
Constructor: public Reflection()

五、获取非构造方法

import java.lang.reflect.Method;

public class Reflection {

    public Reflection() {
        System.out.println("Public Constructor");
    }

    private void m() {
    }

    public static void main(String[] args) {
        // 获取所有声明的方法
        Method[] declaredMethods = Reflection.class.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println("Declared method: " + method);
        }
        // 获取所有公有方法
        Method[] methods = Reflection.class.getMethods();
        for (Method method : methods) {
            System.out.println("Method: " + method);
        }
    }
}

运行结果

Declared method: public static void Reflection.main(java.lang.String[])
Declared method: private void Reflection.m()
Method: public static void Reflection.main(java.lang.String[])
Method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
Method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
Method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
Method: public boolean java.lang.Object.equals(java.lang.Object)
Method: public java.lang.String java.lang.Object.toString()
Method: public native int java.lang.Object.hashCode()
Method: public final native java.lang.Class java.lang.Object.getClass()
Method: public final native void java.lang.Object.notify()
Method: public final native void java.lang.Object.notifyAll()

六、访问私有方法

import java.lang.reflect.Method;

public class Reflection {

    private String property = "Original";

    private void m(String value) {
        this.property = value;
    }

    public String getProperty() {
        return this.property;
    }

    public static void main(String[] args) throws Exception {
        Reflection reflection = new Reflection();
        Class clazz = reflection.getClass();
        Method method = clazz.getDeclaredMethod("m", String.class);
        if (method != null) {
            method.setAccessible(true);
            method.invoke(reflection, "Changed");
        }
        System.out.println(reflection.getProperty());
    }
}

运行结果

Changed

七、修改私有属性

import java.lang.reflect.Field;

public class Reflection {

    private String property = "Original";

    public String getProperty() {
        return this.property;
    }

    public static void main(String[] args) throws Exception {
        Reflection reflection = new Reflection();
        Class clazz = reflection.getClass();
        Field property = clazz.getDeclaredField("property");
        if (property != null) {
            property.setAccessible(true);
            property.set(reflection, "Changed");
            System.out.println(reflection.getProperty());
        }
    }
}

运行结果

Changed