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();
}
}