Last active
December 22, 2017 03:00
-
-
Save mattermon/e18c9d19c0a67161ef140b0cf4562f8a to your computer and use it in GitHub Desktop.
反射调用代码
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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