一、反射机制
Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。
以上是比较官方的解释, 简而言之就是通过 jvm 编译产生的 .class 文件来反映出对应的类(.java)文件罢了.
二、反射的基本步骤
- 获得Class对象
- 获得类的属性, 方法或构造函数
- 创建对象, 访问属性,以及调用方法
举个栗子:
// 获得Class对象
Class cls = Class.forName("my.Student");
// 取得对象的所有方法及成员变量
Method[] methods = cls.getMethods();
Field[] fields = cls.getFields();
// 创建对象
Object obj = cls.newInstance();
通过这三步就可以基本实现一个通过 class 反射对象的一个过程. 乍一看可能有点懵逼, 这有什么用, 难道老老实实的 new 一个对象不好吗, 当然在可以直接new对象的情况下, 肯定要选择简单明了的方法, 但是在某些特定情况下直接创建对象会变得很不现实, 比如:
- 如果我只知道一个类的名称/或者它的一个实例对象, 我就能把这个类的所有方法和变量的信息找出来(方法名,变量名,方法,修饰符,类型,方法参数等等所有信息)。
- 如果我还明确知道这个类里某个变量的名称,我还能得到这个变量当前的值。
- 当然,如果我明确知道这个类里的某个方法名+参数个数类型,我还能通过传递参数来运行那个类里的那个方法。
再举个完整的栗子:
package my;
// 学生类
public class Student {
private int id;
private String name;
private String phone;
public Student() {
}
public Student(int id, String name, String phone)
{
this.id = id;
this.name = name;
this.phone = phone;
}
@Override
public boolean equals(Object obj) {
if (this.getClass().isInstance(obj)) {
return this.id == ((Student) obj).id;
} else if(String.class.isInstance(obj)) {
return this.name.equals((String)obj);
} else if(Integer.class.isInstance(obj)) {
return this.id == (Integer)obj;
}
return false;
}
@Override
public String toString() {
return "(" + id + "," + name + "," + phone + ")";
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
}
测试类
package my;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Hello {
public static void isStudentByObject(Object obj)
{
Class cls = Student.class;
if (cls.isInstance(obj))
{
System.out.println("是学生类的实例..");
}
}
public static void isStudentByName(Object obj)
{
String clsName = obj.getClass().getName();
if (clsName.equals("my.Student")) {
System.out.println("是学生类的实例");
}
}
public static Method[] getMethodList() throws ClassNotFoundException {
Class cls = Class.forName("my.Student");
Method[] methods = cls.getMethods();
Field[] fields = cls.getFields();
return methods;
}
public static void getMethod(Class clas) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
String methodName = "setId";
// 创建实例
Object obj = clas.newInstance();
// 方法参数类型列表
Class[] parameterTypes = { int.class };
Method m = clas.getMethod(methodName, parameterTypes);
// 方法参数列表
Object[] paramsForMethod = { 123 };
// 调用方法
m.invoke(obj, paramsForMethod);
// 打印
System.out.println((Student)obj);
System.out.println("ok!");
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Class cls = Class.forName("my.Student");
getMethod(cls);
}
}
代码运行结果如下:
done!