|
|
package com.gizwits.opensource.appkit.utils;
|
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
|
/**
|
|
|
* Created by zhaopan on 2016/11/7.
|
|
|
* e-mail: kangqiao610@gmail.com
|
|
|
*/
|
|
|
public class ReflectionUtils {
|
|
|
|
|
|
/**
|
|
|
* 循环向上转型, 获取对象的 DeclaredMethod
|
|
|
*
|
|
|
* @param object : 子类对象
|
|
|
* @param methodName : 父类中的方法名
|
|
|
* @param parameterTypes : 父类中的方法参数类型
|
|
|
* @return 父类中的方法对象
|
|
|
*/
|
|
|
|
|
|
public static Method getDeclaredMethod(Object object, String methodName, Class<?>... parameterTypes) {
|
|
|
Method method = null;
|
|
|
|
|
|
for (Class<?> clazz = object.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
|
|
|
try {
|
|
|
method = clazz.getDeclaredMethod(methodName, parameterTypes);
|
|
|
return method;
|
|
|
} catch (Exception e) {
|
|
|
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
|
|
|
//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 直接调用对象方法, 而忽略修饰符(private, protected, default)
|
|
|
*
|
|
|
* @param object : 子类对象
|
|
|
* @param methodName : 父类中的方法名
|
|
|
* @param parameterTypes : 父类中的方法参数类型
|
|
|
* @param parameters : 父类中的方法参数
|
|
|
* @return 父类中方法的执行结果
|
|
|
*/
|
|
|
|
|
|
public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes,
|
|
|
Object[] parameters) {
|
|
|
//根据 对象、方法名和对应的方法参数 通过反射 调用上面的方法获取 Method 对象
|
|
|
Method method = getDeclaredMethod(object, methodName, parameterTypes);
|
|
|
|
|
|
//抑制Java对方法进行检查,主要是针对私有方法而言
|
|
|
method.setAccessible(true);
|
|
|
|
|
|
try {
|
|
|
if (null != method) {
|
|
|
|
|
|
//调用object 的 method 所代表的方法,其方法的参数是 parameters
|
|
|
return method.invoke(object, parameters);
|
|
|
}
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
e.printStackTrace();
|
|
|
} catch (IllegalAccessException e) {
|
|
|
e.printStackTrace();
|
|
|
} catch (InvocationTargetException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 循环向上转型, 获取对象的 DeclaredField
|
|
|
*
|
|
|
* @param object : 子类对象
|
|
|
* @param fieldName : 父类中的属性名
|
|
|
* @return 父类中的属性对象
|
|
|
*/
|
|
|
|
|
|
public static Field getDeclaredField(Object object, String fieldName) {
|
|
|
Field field = null;
|
|
|
|
|
|
Class<?> clazz = object.getClass();
|
|
|
|
|
|
for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
|
|
|
try {
|
|
|
field = clazz.getDeclaredField(fieldName);
|
|
|
return field;
|
|
|
} catch (Exception e) {
|
|
|
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
|
|
|
//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
public static Object getFieldValue(Object obj, String fieldName) {
|
|
|
if (obj == null || TextUtils.isEmpty(fieldName)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
Class<?> clazz = obj.getClass();
|
|
|
while (clazz != Object.class) {
|
|
|
try {
|
|
|
Field field = clazz.getDeclaredField(fieldName);
|
|
|
field.setAccessible(true);
|
|
|
return field.get(obj);
|
|
|
} catch (Exception e) {
|
|
|
}
|
|
|
clazz = clazz.getSuperclass();
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
public static void setFieldValue(Object obj, String fieldName, Object value) {
|
|
|
if (obj == null || TextUtils.isEmpty(fieldName)) {
|
|
|
return;
|
|
|
}
|
|
|
Class<?> clazz = obj.getClass();
|
|
|
while (clazz != Object.class) {
|
|
|
try {
|
|
|
Field field = clazz.getDeclaredField(fieldName);
|
|
|
field.setAccessible(true);
|
|
|
field.set(obj, value);
|
|
|
return;
|
|
|
} catch (Exception e) {
|
|
|
}
|
|
|
clazz = clazz.getSuperclass();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|