反射的作用
在运行时判定任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判定任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
工具类
这里给大家提供一个反射工具类,里面的方法都有注释
常用的就是四个方法
public class ReflectionHelper {
/**
* 传入类名去返回一个对应的Class
* @param className
* @return
*/
public static Class getClass(String className) {
Class c = null;
try {
//根据类名获取class
c = Class.forName(className);
} catch (ClassNotFoundException e) {
// e.printStackTrace();
}
return c;
}
/**
* 用指定类的构造方法创建一个实例
*
* @param clazz Class
* @param params 构造参数
* @return 实例
*/
public static Object newInstance(Class clazz, Object... params) {
if (clazz != null) {
//获取对应class的构造函数
Constructor[] ctors = clazz.getDeclaredConstructors();
Constructor constructor = null;
int paramsCount = params == null ? 0 : params.length;
for (Constructor ctor : ctors) {
constructor = ctor;
//用参数个数匹配对应的构造函数
if (constructor.getGenericParameterTypes().length == paramsCount)
break;
}
if (constructor != null) {
//设置私有的构造函数也可以取到
constructor.setAccessible(true);
try {
//实例化
return constructor.newInstance(params);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 调用一个类的方法
*
* @param receiver 方法的接受者,通常是clazz的实例object。如果调用静态方法则传null。
* @param clazz Class
* @param methodName 方法名
* @param args 参数,可为null
* @return
*/
public static Object invokeMethod(Object receiver, Class clazz, String methodName, Object... args) {
if (clazz == null || methodName == null) {
return null;
}
//获取到所有的方法
Method[] allMethods = clazz.getDeclaredMethods();
int argsCount = args == null ? 0 : args.length;
int methodArgsCount = 0;
for (Method method : allMethods) {
methodArgsCount = method.getParameterTypes() == null ? 0 : method.getParameterTypes().length;
if (methodName.equals(method.getName())
&& argsCount == methodArgsCount) {
//私有方法也可以获取
method.setAccessible(true);
try {
//方法调用
return method.invoke(receiver, args);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
return null;
}
/**
* 获取一个变量
* @param receiver class的实例object
* @param clazz class
* @param fieldName 要获取的变量名
* @param <T> 返回的值
* @return
*/
public static <T> T getField(Object receiver, Class clazz, String fieldName) {
if (clazz == null || fieldName == null) {
return null;
}
T result = null;
try {
//找到对应变量
Field field = clazz.getDeclaredField(fieldName);
//可获取私有变量
field.setAccessible(true);
//获取对应值
result = (T) field.get(receiver);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
使用示例
现在有一个类
class Person {
private int age = 10;
private void show() {
System.out.println("age = " + age);
}
}
现在我们想获取其中的age的值和对应的show方法;
可以看到都是私有类型的,但是使用反射就可以获取到和调用到;
//获取到class
Class aClass = ReflectionHelper.getClass(Person.class.getName());
//获取到对应实例
Object object = ReflectionHelper.newInstance(aClass);
//取值
Object age = ReflectionHelper.getField(object, aClass, "age");
System.out.println(age);
//调用相应方法
ReflectionHelper.invokeMethod(object, aClass, "show");
运行结果:
10
age = 10