Skip to content

Instantly share code, notes, and snippets.

@mattermon
Last active December 22, 2017 03:00
Show Gist options
  • Save mattermon/e18c9d19c0a67161ef140b0cf4562f8a to your computer and use it in GitHub Desktop.
Save mattermon/e18c9d19c0a67161ef140b0cf4562f8a to your computer and use it in GitHub Desktop.
反射调用代码
package com.example.dex.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectUtils {
/**
* Locates a given field anywhere in the class inheritance hierarchy.
* @param instance an object to search the field into.
* @param name field name
* @return a field object
* @throws NoSuchFieldException if the field cannot be located
*/
public static Field findField(Object instance, String name) throws NoSuchFieldException {
for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
try {
Field field = clazz.getDeclaredField(name);
if (!field.isAccessible()) {
field.setAccessible(true);
}
return field;
} catch (NoSuchFieldException e) {
// ignore and search next
}
}
throw new NoSuchFieldException("Field " + name + " not found in " + instance.getClass());
}
/**
* Locates a given method anywhere in the class inheritance hierarchy.
* @param instance an object to search the method into.
* @param name method name
* @param parameterTypes method parameter types
* @return a method object
* @throws NoSuchMethodException if the method cannot be located
*/
public static Method findMethod(Object instance, String name, Class<?>... parameterTypes)
throws NoSuchMethodException {
for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
try {
Method method = clazz.getDeclaredMethod(name, parameterTypes);
if (!method.isAccessible()) {
method.setAccessible(true);
}
return method;
} catch (NoSuchMethodException e) {
// ignore and search next
}
}
throw new NoSuchMethodException("Method " + name + " with parameters " +
Arrays.asList(parameterTypes) + " not found in " + instance.getClass());
}
/**
* 循环向上转型, 获取对象的 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;
}
public static Object invokeStaticMethod(String className, String methodName, Class<?>[] parameterTypes, Object[] parameters)
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Class<?> threadClazz = Class.forName(className);
Method method = threadClazz.getMethod(methodName, parameterTypes);
return method.invoke(null, new Object[]{});
}
/**
* 直接调用对象方法, 而忽略修饰符(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;
}
/**
* 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
*
* @param object
* : 子类对象
* @param fieldName
* : 父类中的属性名
* @param value
* : 将要设置的值
*/
public static void setFieldValue(Object object, String fieldName, Object value) {
// 根据 对象和属性名通过反射 调用上面的方法获取 Field对象
Field field = getDeclaredField(object, fieldName);
// 抑制Java对其的检查
field.setAccessible(true);
try {
// 将 object 中 field 所代表的值 设置为 value
field.set(object, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
*
* @param object
* : 子类对象
* @param fieldName
* : 父类中的属性名
* @return : 父类中的属性值
*/
public static Object getFieldValue(Object object, String fieldName) {
// 根据 对象和属性名通过反射 调用上面的方法获取 Field对象
Field field = getDeclaredField(object, fieldName);
// 抑制Java对其的检查
field.setAccessible(true);
try {
// 获取 object 中 field 所代表的属性值
return field.get(object);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment