Java反射 创建对象

Java反射提供了动态创建对象的能力,即在程序运行时根据类名或者Class对象来创建一个类的实例。可以通过反射的方式调用类的构造方法来实现这个功能。

Class 类代表一个类的类型,它可以获取类的信息、属性、方法等,我们可以通过以下三种方式获取类的 Class 对象:
1、使用 .class 语法糖,例如 String.class、Integer.class。

Class<?> clazz = String.class;
System.out.println(clazz);

2、调用对象的 .getClass() 方法,例如 “hello”.getClass()、1.getClass()。

String str = "Hello World";
Class<?> clazz = str.getClass();
System.out.println(clazz);

3、使用 Class.forName() 方法,例如 Class.forName(“java.lang.String”)。

try {
    Class<?> clazz = Class.forName("java.lang.String");
    System.out.println(clazz);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

下面是一个使用反射创建对象的示例代码:

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

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

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

    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 class Main {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("Person");
        // 使用默认构造函数创建对象
        Person person1 = (Person) clazz.newInstance();
        System.out.println(person1.getName()); // 输出 "Unknown"

        // 使用带参数的构造函数创建对象
        Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
        Person person2 = (Person) constructor.newInstance("Tom", 20);
        System.out.println(person2.getName()); // 输出 "Tom"
        System.out.println(person2.getAge()); // 输出 20
    }
}

上面的代码中,我们使用Class.forName方法获取了Person类的Class对象,并使用newInstance方法创建了一个实例。由于Person类中没有无参构造方法,我们需要使用getConstructor方法获取带参数的构造函数,然后使用newInstance方法创建实例。创建实例后,我们可以使用相应的getter和setter方法设置和获取属性。

需要注意的是,使用反射创建对象时需要处理ClassNotFoundException、InstantiationException、IllegalAccessException和InvocationTargetException等异常。同时,使用反射创建对象的效率要比直接调用构造方法低,因为反射需要进行额外的类加载和动态绑定。因此,仅在必要时才应该使用反射创建对象。