15_Java反射机制——3.创建运行时类的对象

问题1: Class 对象 (或 Class 实例) 能做什么?

1. Class 对象 对应于一个 .class 文件,即 运行时类。
2. 调用 Class 对象 的 newInstance() 方法,可以用来 创建 运行时类的对象。

要 求: 
    1)类必须有一个无参数的构造器。
    2)类的构造器的访问权限需要足够。

问题2: 难道没有无参的构造器就不能创建对象了吗?

不是!只要在操作的时候,明确地调用类中的构造器, 并将参数传递进去之后,才可以实例化操作。

步骤如下:
    1)通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类
       型的构造器。
    2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数(参数个数可以为0)。
    3)通过Constructor实例化对象。

    eg:
    // 1. 根据 全类名 获取  Class 实例 ——  运行时类(即 对应一个 .class 文件)
    String  className = "com.atzwx.java.Employee";
    Class clazz = Class.forName(className);
    // 2. 通过 运行时类 获取 类成员(构造器、方法、属性)
    // public Employee(Integer id, String name) {
    //    this.id = id;
    //    this.name = name;
    //}
    Constructor declaredConstructor = clazz.getDeclaredConstructor(Integer.class, String.class);
    // 3. 通过Constructor实例化对象。
    Employee employee = (Employee) declaredConstructor.newInstance(25, "worker");               

举 例 : 创建运行时类的对象

【Employee】

//package com.atzwx.java;

public class Employee {

    private Integer id = 1;

    private String name;

    private Integer age = 20;

    private String address;

    public int works = 90;

    public Employee() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getWorks() {
        return works;
    }

    public void setWorks(int works) {
        this.works = works;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", works=" + works +
                '}';
    }

    //@Override
    public void work() {
        System.out.println("Employee.work");
    }

    //@Override
    public void say() {
        System.out.println("Employee.say");
    }

    //@Override
    public void study() {
        System.out.println("Employee.study");
    }
}

【ReflectTest】

//package com.atzwx.test;

import com.atzwx.java.Employee;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectTest {

    /**
     * 通过 Class 对象,调用 newInstance() 方法, 来 创建 运行时类的对象
     * @throws Exception
     */
    @Test
    public void reflectTest() throws Exception {

        // 说明: Class 是一个用来 描述类 的 类 ,通过 Class 类 可以获取 一个 类的相关信息
        // 1. 根据 全类名 获取  Class 实例 ——  运行时类(即 对应一个 .class 文件)
        String  className = "com.atzwx.java.Employee"; // Employee 类的全类名,按自己的实际全类名来填写
        Class clazz = Class.forName(className);
        System.out.println("clazz: " + clazz); // cclazz: class com.atzwx.java.Employee
        System.out.println();

        // 2. 通过 Class 实例 ( 对象 ) 的 newInstance() 方法,来获取 运行时类 的 实例 (对象)
        Object realObj = clazz.newInstance();
        System.out.println("realObj: " + realObj); // realObj: Employee{id=1, name='null', age=20, address='null', works=90}
        System.out.println();

        // 3. 通过 运行时类 获取 类成员(构造器、方法、属性)
        Constructor constructor = clazz.getConstructor();
        System.out.println("constructor: " + constructor); // constructor: public com.atzwx.java.Employee()
        Employee employee = (Employee) constructor.newInstance();
        System.out.println("employee: " + employee); // employee: Employee{id=1, name='null', age=20, address='null', works=90}
        System.out.println();

        Method method = clazz.getMethod("work");
        System.out.println("method: " + method); // method: public void com.atzwx.java.Employee.work()
        method.invoke(realObj); // Employee.work
        System.out.println();

        Method methodDeclared = clazz.getDeclaredMethod("say");
        System.out.println("methodDeclared: "+ methodDeclared); // methodDeclared: public void com.atzwx.java.Employee.say()
        methodDeclared.invoke(realObj); // Employee.say
        System.out.println();

        Field field = clazz.getField("works");
        System.out.println("field: " + field); // field: public int com.atzwx.java.Employee.works
        System.out.println();

    }

}
posted @ 2022-03-20 23:05  hellozwx  阅读(62)  评论(0编辑  收藏  举报