Java反射机制:
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
示例类
package reflect;
public class Hello {
private String name;
public Hello() {
super();
}
public Hello(String name) {
super();
this.name = name;
}
public void sayHello() {
System.out.println((name == null ? "" : name) + " say hello");
}
public void sayHello(String toSomeOne) {
System.out.println((name == null ? "" : name) + " say hello to "
+ toSomeOne);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
实例化Class类的三种方式
java程序运行时,所有的java类在JVM中都表现为java.lang.Class类的实例化对象。
/*
* 获取class三种方式
*/
//helloClass表示Hello类的类类型(class type)
//1.Class.forName(类的全称),运行时动态加载类
Class<?> helloClass=Class.forName("reflect.Hello");
//2.类的对象.getClass()
Hello hello=new Hello();
Class<?> helloClass2 = hello.getClass();
//3.类.class
Class<?> helloClass3=Hello.class;
获取类中方法信息
/**
* 打印类中方法信息
*
* @param clazz
*/
public static void printClassMethodsMessage(Class<?> clazz) {
// 获取类的名称
System.out.println("类的名称是:" + clazz.getName());
/*
* 获取类的方法 一个方法对应一个Method对象 getMethods()获取所有public修饰的方法(包括从父类中继承的方法)
* getDeclaredMethods()获取所有在该类声明的方法
*/
Method[] methods = clazz.getDeclaredMethods();
System.out.println("类中包含方法:");
for (Method method : methods) {
// 获取返回类型
Class<?> returnType = method.getReturnType();
System.out.print(returnType.getName() + " ");
// 打印方法名
System.out.print(method.getName());
System.out.print("(");
// 获取参数类型
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> cls : parameterTypes) {
System.out.print(cls.getName() + ",");
}
System.out.println(")");
}
}
获取类中成员变量信息
/**
* 打印类中成员变量信息
*
* @param clazz
*/
public static void printClassFieldsMessage(Class<?> clazz) {
// 获取类的名称
System.out.println("类的名称是:" + clazz.getName());
/*
* 获取类中的成员变量 一个成员变量对应一个Field对象
* getFields()获取类中所有public修饰的成员变量(包括从父类继承的成员变量)
* getDeclaredFields()获取类中声明的所有成员变量
*/
Field[] fields = clazz.getDeclaredFields();
System.out.println("类中包含成员变量:");
for (Field field : fields) {
// 获取变量类型
Class<?> type = field.getType();
// 获取变量名称
String fieldName = field.getName();
System.out.println(type.getName() + " " + fieldName);
}
}
获取类中构造函数信息
/**
* 打印构造方法信息
* @param clazz
*/
public static void printClassConstructorMessage(Class<?> clazz) {
// 获取类的名称
System.out.println("类的名称是:" + clazz.getName());
/*
* 获取构造方法 一个构造方法对应一个Constructor对象
* getConstructors()获取所有public修饰的构造方法(包括从父类继承的构造方法)
* getDeclaredConstructors()获取所有类中声明的构造方法
*/
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
System.out.println("类中构造方法:");
for (Constructor<?> constructor : constructors) {
// 构造方法名
System.out.print(constructor.getName() + "(");
// 获取构造方法参数
Class<?>[] parameterTypes = constructor.getParameterTypes();
for (Class<?> cls : parameterTypes) {
System.out.print(cls.getName());
}
System.out.println(")");
}
}
调用某方法
/**
* 通过反射调用某方法
*
* @param clazz
* 类类型
* @param methodName
* 方法名
* @param parameterTypes
* 方法参数类型
* @param args
* 方法传入参数
*/
public static Object methodInvoke(Class<?> clazz, String methodName,
Class<?>[] parameterTypes, Object[] args) {
Object res = new Object();
try {
// 通过方法名、参数类型可以确定唯一的成员方法
Method method = clazz.getMethod(methodName, parameterTypes);
res = method.invoke(clazz.newInstance(), args);
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
改变成员变量值
/**
* 通过反射改变对象变量值
* @param obj
* 需要改变成员变量值的对象
* @param fieldName
* 需要改变的成员变量名
* @param value
* 改变成员变量的值
*/
public static synchronized void changeFieldValue(Object obj,
String fieldName, Object value) {
try {
Class<?> clazz = obj.getClass();
// 获取成员变量
Field field = clazz.getDeclaredField(fieldName);
// 成员变量设置为可修改
field.setAccessible(true);
// 修改成员变量值
field.set(obj, value);
// 成员变量设置为不可修改
field.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
}
测试类
package reflect;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
/*
* 获取class三种方式
*/
//helloClass表示Hello类的类类型(class type)
//1.Class.forName(类的全称),运行时动态加载类
Class<?> helloClass=Class.forName("reflect.Hello");
// //2.类的对象.getClass()
// Hello hello=new Hello();
// Class<?> helloClass2 = hello.getClass();
//
// //3.类.class
// Class<?> helloClass3=Hello.class;
ClassUtil.printClassMethodsMessage(helloClass);
System.out.println("=========================");
ClassUtil.printClassFieldsMessage(helloClass);
System.out.println("=========================");
ClassUtil.printClassConstructorMessage(helloClass);
System.out.println("=========================");
Class<?>[] parameterTypes1 ={};
Object[] args1={};
System.out.println("调用sayHello():");
ClassUtil.methodInvoke(helloClass, "sayHello", parameterTypes1, args1);
System.out.println("=========================");
Class<?> [] parameterTypes2={String.class};
Object[] args2={"tom"};
System.out.println("调用sayHello(String name):");
ClassUtil.methodInvoke(helloClass, "sayHello", parameterTypes2, args2);
System.out.println("=========================");
System.out.println("通过反射改变name值:");
Hello hello=new Hello("tom");
hello.sayHello();
ClassUtil.changeFieldValue(hello, "name", "jerry");
hello.sayHello();
System.out.println("=========================");
}
}
运行结果
参考资料:
慕课网:反射——Java高级开发必须懂的
^ ^ 欢迎批评指正