反射的概念
反射机制是指在程序运行的时候,对于任意一个类都能获取其所有属性以及方法,对于任意一个对象都可以动态的调用其任意一个方法。这种动态的获取类和对象的信息,以及动态的调用对象的方法的功能称为Java语言的反射机制。
Java中的对象有两种类型:编译时(由.java源代码到.class文件的过程)类型和运行时类型。编译时类型是指在声明对象时所采用的类型,运行时类型是指为对象赋值时所采用的类型。
Person person = new Student();
在这里person对象的编译时类型为Person,运行时类型为Student,因此无法在编译时获取到Student类中定义的方法。
**准备工作:**这里定义一个Employee实体类,重写toString方法,添加静态代码块是为了测试在对象初始化时,employee对象被加载到JVM中。代码如下:
package com.yun.reflect.entity;
/**
* @Author: Crush
* enumber 员工编号
* ename 员工姓名
* salary 员工薪水
* dname 部门名称
*/
public class Employee {
private Integer enumber;
public String ename;
private Float salary;
private String dname;
static {
System.out.println("employee已经被加载到JVM中,初始化成功");
}
public Employee() {
System.out.println("默认构造方法已经执行");
}
public Employee(Integer enumber, String ename, Float salary, String dname) {
this.enumber = enumber;
this.ename = ename;
this.salary = salary;
this.dname = dname;
System.out.println("employee带参数构造方法已经被执行");
}
@Override
public String toString() {
return "Employee{" +
"enumber=" + enumber +
", ename='" + ename + '\'' +
", salary=" + salary +
", dname='" + dname + '\'' +
'}';
}
public Integer getEnumber() {
return enumber;
}
public void setEnumber(Integer enumber) {
this.enumber = enumber;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public Employee updateSalary(Float val) {
this.salary = this.salary + val;
System.out.println("薪资调制" + this.salary);
return this;
}
}
反射的步骤
-
获取想要操作的类的Class对象,该Class对象是反射的核心,通过它可以调用类的任意方法。
-
调用Class对象所对应的类的定义的方法,这是反射的使用阶段。
-
使用反射API来获取类的属性或方法
代码如下:
package com.yun.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @Author: Crush
*/
public class ClassBasic {
public static void main(String[] args) {
try{
// 1. 获取Employee类的Class对象
Class basicClass = Class.forName("com.yun.reflect.entity.Employee");
// 2.获取Employee类的所有的方法的信息
Method[] methods = basicClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("================================");
// 3.获取Employee类的所有成员的属性信息
Field [] fields = basicClass.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.toString());
}
System.out.println("================================");
// 4.获取Employee类的所有的构造方法的信息
Constructor [] constructors = basicClass.getDeclaredConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor.toString());
}
}catch (ClassNotFoundException e ){
e.printStackTrace();
}
}
}
创建对象方式
- 使用Class对象的newInstance方法,要求Class具有无参数构造函数。
- 使用Class对象获取指定的Constructor对象,再调用对象newInstance方法创建Class对象对应类的实例。
Java反射API
Java的反射API主要用于在运行过程中动态生成类、接口或对象等信息。
Class类
用于获取类的属性,方法等信息
Field类
表示类的成员变量,用于获取和设置类中的属性值
Constructor类
表示类的构造方法
Method类
表示类的方法,用于获取方法的描述信息或者执行某个方法