Java反射

Java反射是Java语言提供的一种在运行时动态访问和操作类、对象、方法、字段等程序元素的机制。它允许程序在不提前知道类具体信息的情况下,通过类的元数据(Class对象)来获取类的结构信息,并动态创建对象、调用方法、访问或修改字段等。

反射机制的核心是java.lang.Class类,它是所有类的元数据表示,通过它可以获取类的各种信息(如字段、方法、构造器等)。

反射的核心类及主要方法

1. Class类(反射的入口)

Class类是反射操作的基础,用于表示类的字节码信息。

获取Class对象的方法:

java 复制代码
// 1. 通过类名.class获取
Class<?> clazz1 = Person.class;

// 2. 通过对象.getClass()获取
Person person = new Person();
Class<?> clazz2 = person.getClass();

// 3. 通过Class.forName("全类名")获取(常用,可动态加载类)
Class<?> clazz3 = Class.forName("com.example.Person");
java 复制代码
class Main {

    public static void main(String[] args) {
        Class<?> personClass = Person.class;
        System.out.println(personClass.getName());
        Person person = new Person("张三", 18);
        Class<?> aClass = person.getClass();
        System.out.println(aClass.getSuperclass());
        try {
            Class<?> person1 = Class.forName("Person");
            for (Class<?> item : person1.getInterfaces()){
                System.out.println(item.getSimpleName());
            }

        } catch (ClassNotFoundException e) {


        }

    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void greet(String message) {
        System.out.println(name + " says: " + message);
    }
}

Class类的主要方法:

方法 说明
String getName() 获取类的全限定名(包名+类名)
String getSimpleName() 获取类的简单名称(仅类名)
Class<?> getSuperclass() 获取父类的Class对象
Class<?>[] getInterfaces() 获取实现的所有接口
Field[] getFields() 获取所有公共(public)字段(包括父类)
Field[] getDeclaredFields() 获取所有字段(包括私有、默认、保护,不包括父类)
Method[] getMethods() 获取所有公共方法(包括父类)
Method[] getDeclaredMethods() 获取所有方法(包括私有、默认、保护,不包括父类)
Constructor<?>[] getConstructors() 获取所有公共构造器
Constructor<?>[] getDeclaredConstructors() 获取所有构造器(包括私有)
Object newInstance() 通过无参构造器创建对象(已过时,推荐用Constructor
2. Field类(表示类的字段)

用于访问和修改类的成员变量(字段)。

主要方法:

方法 说明
String getName() 获取字段名称
Class<?> getType() 获取字段的数据类型
void setAccessible(boolean flag) 设置是否允许访问私有字段(true表示允许)
Object get(Object obj) 获取指定对象的该字段值(静态字段可传null
void set(Object obj, Object value) 设置指定对象的该字段值(静态字段可传null
int getModifiers() 获取字段的修饰符(如publicprivate等,需配合Modifier类解析)
java 复制代码
class Main {

    public static void main(String[] args) {
        Class<?> personClass = Person.class;
        try {

            Field name = personClass.getDeclaredField("name");
            name.setAccessible(true);
            System.out.println(name.get(new Person("John", 30)));

            Person person=new Person("test", 30);
            System.out.println(name.get(person));

        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }


    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void greet(String message) {
        System.out.println(name + " says: " + message);
    }
}
3. Method类(表示类的方法)

用于动态调用类的方法(包括私有方法)。

主要方法:

方法 说明
String getName() 获取方法名称
Class<?> getReturnType() 获取方法的返回值类型
Class<?>[] getParameterTypes() 获取方法的参数类型数组
void setAccessible(boolean flag) 设置是否允许访问私有方法
Object invoke(Object obj, Object... args) 调用指定对象的该方法(静态方法可传nullargs为方法参数)
int getModifiers() 获取方法的修饰符
java 复制代码
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Main {

    public static void main(String[] args) {
        Class<?> personClass = Person.class;
        try {
            Method greet = personClass.getMethod("greet", String.class);
            greet.setAccessible( true);
            greet.invoke(new Person("John", 30), "Hello, World!");
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }


    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void greet(String message) {
        System.out.println(name + " says: " + message);
    }
}
4. Constructor类(表示类的构造器)

用于动态创建类的实例(支持有参构造)。

主要方法:

方法 说明
Class<?>[] getParameterTypes() 获取构造器的参数类型数组
void setAccessible(boolean flag) 设置是否允许访问私有构造器
Object newInstance(Object... args) 通过该构造器创建对象(args为构造器参数)
int getModifiers() 获取构造器的修饰符
java 复制代码
class Main {

    public static void main(String[] args) {
        Class<?> personClass = Person.class;
        try {
            Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
            Object johnDoe = constructor.newInstance("John Doe", 30);

            Field name = personClass.getDeclaredField("name");
            name.setAccessible(true);
            System.out.println("Name: " + name.get(johnDoe));

        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException |
                 NoSuchFieldException e) {
            throw new RuntimeException(e);
        }

    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void greet(String message) {
        System.out.println(name + " says: " + message);
    }
}

反射操作示例(综合应用)

java 复制代码
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Main {

    public static void main(String[] args) {
        Class<?> personClass = Person.class;
        try {
            Constructor<?> declaredConstructor = personClass.getDeclaredConstructor(String.class, int.class);
            declaredConstructor.setAccessible(true);
            Object john = declaredConstructor.newInstance("John", 30);

            Field name = personClass.getDeclaredField("name");
            name.setAccessible(true);

            System.out.println("Name: " + name.get(john));


            Method sayHello = personClass.getDeclaredMethod("sayHello");
            name.set(john, "John Doe");
            sayHello.setAccessible(true);
            sayHello.invoke(john);

            Method sayHello2 = personClass.getDeclaredMethod("sayHello2", String.class);
            sayHello2.setAccessible(true);
            sayHello2.invoke(john, "hello");

        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException |
                 NoSuchFieldException e) {
            throw new RuntimeException(e);
        }

    }
}



class Person {
    private String name;
    private int age;

    public Person() {}

    private Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private void sayHello() {
        System.out.println("Hello, I'm " + name);
    }
    private void sayHello2(String say) {
        System.out.println( name+"say"+say);
    }

    public int getAge() {
        return age;
    }
}