Java反射 获取/修改构造方法

在Java反射中,我们可以通过 Class 类的 getConstructor 和 getDeclaredConstructor 方法获取一个类的构造方法,并通过 Constructor 类来调用或修改该构造方法。同时,我们也可以使用 Constructor 类的 newInstance 方法来创建一个类的实例。

具体来说,getConstructor 方法用于获取一个类的指定公共构造方法,getDeclaredConstructor 方法用于获取一个类的指定构造方法(可以是私有的、受保护的等等),这两个方法均返回一个 Constructor 对象。我们可以使用 Constructor 类的 newInstance 方法来创建一个类的实例,也可以使用 Constructor 类的 setAccessible 方法来设置构造方法的可访问性。

以下是一个简单的示例代码,用于演示如何获取并调用构造方法:

public class Person {
    private String name;
    private int age;

    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }

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

    public String getName() {
        return this.name;
    }

    public int getAge() {
        return this.age;
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        // 获取 Person 类的两个构造方法
        Constructor<Person> constructor1 = Person.class.getConstructor();
        Constructor<Person> constructor2 = Person.class.getConstructor(String.class, int.class);

        // 创建 Person 类的实例
        Person person1 = constructor1.newInstance();
        Person person2 = constructor2.newInstance("Alice", 20);

        // 输出实例的信息
        System.out.println("Person 1: name = " + person1.getName() + ", age = " + person1.getAge());
        System.out.println("Person 2: name = " + person2.getName() + ", age = " + person2.getAge());
    }
}

在上面的示例中,我们首先通过 Person.class.getConstructor 方法获取了 Person 类的两个构造方法,一个是不带参数的构造方法,另一个是带两个参数的构造方法。然后,我们使用 Constructor.newInstance 方法创建了两个 Person 类的实例,一个是不带参数的构造方法创建的,另一个是带参数的构造方法创建的。最后,我们输出了这两个实例的信息。

我们还可以使用 Constructor 类的 getParameterTypes 方法获取构造方法的参数类型,使用 getModifiers 方法获取构造方法的修饰符,以及使用 getName 方法获取构造方法的名称等信息。例如,以下代码演示了如何获取构造方法的参数类型:

public class Main {
    public static void main(String[] args) throws Exception {
        Constructor<Person> constructor = Person.class.getConstructor(String.class, int.class);
        Class<?>[] parameterTypes = constructor.getParameterTypes();

        for (Class<?> type : parameterTypes) {
            System.out.println("Parameter type: " + type.getName());
        }
    }
}

输出结果为:
Parameter type: java.lang.String
Parameter type: int

除了获取和修改方法外,反射还可以用于获取和修改类的构造方法。构造方法是用于创建类的对象的方法,可以通过反射来实例化类。

获取构造方法需要使用Class类的getConstructor和getDeclaredConstructor方法,这两个方法分别用于获取类中的公共和私有构造方法。获取构造方法后,我们可以使用newInstance方法来创建类的实例。

修改构造方法的访问权限可以使用setAccessible方法,这个方法可以设置构造方法的访问权限,使得我们可以在不暴露私有构造方法的情况下创建类的实例。

以下是一个使用反射获取和修改构造方法的示例代码:

import java.lang.reflect.Constructor;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        // 获取Person类的构造方法
        Class<Person> personClass = Person.class;
        Constructor<Person> constructor = personClass.getDeclaredConstructor(String.class, int.class);
        constructor.setAccessible(true);

        // 使用构造方法创建Person类的实例
        Person person = constructor.newInstance("Alice", 25);
        System.out.println(person);

        // 修改构造方法的访问权限
        Constructor<Person> publicConstructor = personClass.getConstructor();
        publicConstructor.setAccessible(true);
        Person anotherPerson = publicConstructor.newInstance();
        System.out.println(anotherPerson);
    }
}

class Person {
    private String name;
    private int age;

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

    public Person() {
        this.name = "John";
        this.age = 30;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

在上面的示例代码中,我们首先使用getDeclaredConstructor方法获取了Person类的私有构造方法,并使用setAccessible方法将其访问权限设置为可访问。接着,我们使用newInstance方法创建了一个Person类的实例,并将其输出到控制台。

接着,我们使用getConstructor方法获取了Person类的公共构造方法,并使用setAccessible方法将其访问权限设置为可访问。然后,我们使用newInstance方法创建了另一个Person类的实例,并将其输出到控制台。