什么是反射?
- 反射是运行时动态访问类与对象的技术
- 反射是JDK1.2版本后的高级特性,隶属于java.lang.reflect
反射的核心类
Class类
- Class是JVM中代表“类和接口”的类
- Class对象具体包含了某个特定类的结构信息
- 通过Class对象可获得对应类的构造方法、方法、成员变量
Class核心方法 | 说明 |
---|
Class.forName() | 静态方法,用于获取指定的Class对象 |
classObj.newInstance() | 通过默认的构造方法创建新的对象 |
classObj.getConstructor() | 获得指定的public修饰构造方法Constructor对象 |
classObj.getMethod() | 获得指定的public修饰方法Method对象 |
classObj.getField() | 获得指定的public修饰成员变量Field对象 |
用代码简单的举个例子
- 首先创建一个Entity类Employee类
package com.pro.reflect.entity;
public class Employee {
static {
System.out.println("Employee类已被加载到JVM,并已初始化");
}
private Integer eno;
public String ename;
private Float salary;
private String dname;
public Employee() {
System.out.println("Employee默认构造方法已被执行!");
}
public Employee(Integer eno, String ename, Float salary, String dname) {
this.eno = eno;
this.ename = ename;
this.salary = salary;
this.dname = dname;
System.out.println("Employee带参构造方法已被执行!");
}
public Integer getEno() {
return eno;
}
public void setEno(Integer eno) {
this.eno = eno;
}
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;
}
@Override
public String toString() {
return "Employee{" +
"eno=" + eno +
", ename='" + ename + '\'' +
", salary=" + salary +
", dname='" + dname + '\'' +
'}';
}
public Employee updateSalary(Float val) {
this.salary = this.salary + val;
System.out.println(this.ename + "调薪至" + this.salary + "元");
return this;
}
}
- ClassSample类
package com.pro.reflect;
import com.pro.reflect.entity.Employee;
public class ClassSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
System.out.println("Employee类已被加载到JVM");
Employee emp = (Employee) employeeClass.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
Constructor构造方法类
- Constructor类是对Java类中的构造方法的抽象
- Constructor对象包含了具体类的某个具体构造方法的声明
- 通过Constructor对象调用带参构造方法创建对象
Constructor类核心方法 | 说明 |
---|
classObj.getConstructor() | 获得指定的public修饰构造方法对象 |
constructorObj.newInstance() | 通过默认的构造方法创建新的对象 |
- Constructor类
package com.pro.reflect;
import com.pro.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ConstructorSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
100, "李磊", 3000f, "研发部"
});
System.out.println(employee);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Method方法类
- Method对象是对某个类中的方法的描述
- Method对象使用classObj.getMethod()方法获取
- 通过Method对象调用指定对象的对应方法
Method核心方法 | 说明 |
---|
classObj.getMethod() | 获得指定的public修饰方法对象 |
methodObj.invoke() | 调用指定对象的对应方法 |
- MethodSample类
package com.pro.reflect;
import com.pro.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
100, "李磊", 3000f, "研发部"
});
Method updateSalaryMethod = employeeClass.getMethod("updateSalary", new Class[]{
Float.class
});
Employee employee1 = (Employee)updateSalaryMethod.invoke(employee, new Object[]{1000f});
System.out.println(employee1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Field成员变量类
- Field对应某个具体类中的成员变量的声明
- Field对象使用classObj.getField()方法获取
- 通过Field对象可为某对象成员变量赋值/取值
Field核心方法 | 说明 |
---|
classObj.getField() | 获得指定的public修饰成员变量Field对象 |
fieldObj.set() | 为某对象指定成员变量赋值 |
fieldObj.get() | 获取某对象指定成员变量数值 |
- FieldSample类
package com.pro.reflect;
import com.pro.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class FieldSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee = (Employee)constructor.newInstance(new Object[]{
100, "李磊", 3000f, "研发部"
});
Field enameField = employeeClass.getField("ename");
enameField.set(employee, "李雷");
String ename = (String) enameField.get(employee);
System.out.println("ename:"+ename);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
getDeclared系列方法
- getDeclaredConstuctor(s)|Method(s)|Field(s)获取对应的对象,s是全部对象
- getConstuctor(s)|Method(s)|Field(s)只能获取public对象
- 访问非作用域(私有)内构造方法,方法,成员变量,会抛出异常
package com.pro.reflect;
import com.pro.reflect.entity.Employee;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class getDeclaredSample {
public static void main(String[] args) {
try {
Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
Constructor constructor = employeeClass.getConstructor(new Class[]{
Integer.class, String.class, Float.class, String.class
});
Employee employee = (Employee) constructor.newInstance(new Object[]{
100, "李磊", 3000f, "研发部"
});
Field[] fields = employeeClass.getDeclaredFields();
for (Field field : fields) {
if(field.getModifiers() == 1){
Object val = field.get(employee);
System.out.println(field.getName() + ":" + val);
} else if (field.getModifiers() == 2) {
String methodName = "get" + field.getName().substring(0, 1).toUpperCase()
+ field.getName().substring(1);
Method getMethod = employeeClass.getMethod(methodName);
Object ret = getMethod.invoke(employee);
System.out.println(field.getName() + ":" + ret);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}