org.nervousync.utils.ReflectionUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-jdk11 Show documentation
Show all versions of utils-jdk11 Show documentation
Java utility collections, development by Nervousync Studio (NSYC)
/*
* Licensed to the Nervousync Studio (NSYC) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nervousync.utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import org.nervousync.commons.Globals;
/**
* Reflection Operate Utilities
* 反射操作工具集
*
* @author Steven Wee [email protected]
* @version $Revision: 1.1.4 $ $Date: Jan 13, 2010 16:26:58 $
*/
public final class ReflectionUtils {
/**
* Logger instance
* 日志实例
*/
private static final LoggerUtils.Logger LOGGER = LoggerUtils.getLogger(ReflectionUtils.class);
/**
* Private constructor for ReflectionUtils
* 反射操作工具集的私有构造方法
*/
private ReflectionUtils() {
}
/**
* Parse field name from getter/setter method name
* 从 getter/setter 方法名称解析字段名称
*
* @param methodName method name
* 方法名称
*
* @return parsed field name
* 解析的字段名称
*/
public static String fieldName(final String methodName) {
String fieldName = null;
if (methodName != null) {
if (methodName.startsWith("get") || methodName.startsWith("set")) {
fieldName = methodName.substring(3);
} else if (methodName.startsWith("is")) {
fieldName = methodName.substring(2);
}
}
if (fieldName != null) {
fieldName = StringUtils.uncapitalized(fieldName);
}
return fieldName;
}
/**
* Find constructor method
* 查找构造方法
*
* @param Target class instance
* 目标类实例
* @param clazz Target class instance
* 目标类实例
*
* @return the constructor method
* 构造方法
*/
public static Constructor findConstructor(final Class clazz)
throws SecurityException, NoSuchMethodException {
return findConstructor(clazz, new Class[0]);
}
/**
* Find constructor method
* 查找构造方法
*
* @param Target class instance
* 目标类实例
* @param clazz Target class instance
* 目标类实例
* @param paramTypes the param type class array
* 参数类型类数组
*
* @return the constructor method
* 构造方法
*/
public static Constructor findConstructor(final Class clazz, final Class>[] paramTypes)
throws SecurityException, NoSuchMethodException {
if (paramTypes == null || paramTypes.length == 0) {
return clazz.getDeclaredConstructor();
}
return clazz.getDeclaredConstructor(paramTypes);
}
/**
* Find field instance
*
* Attempt to find a field instance on the supplied argument clazz with the supplied name
.
* Searches all superclasses up to Object
.
*
* 查找字段实例
*
* 尝试使用提供的字段名称在提供的参数 clazz 上查找属性反射对象。搜索所有超类直到 Object
。
*
*
* @param clazz Target class instance
* 目标类实例
* @param name the name of the field
* 字段名称
*
* @return the corresponding Field object, or null
if not found
* 相应的 Field 对象,如果未找到则为 null
*/
public static Field findField(final Class> clazz, final String name) {
return findField(clazz, name, null);
}
/**
* Find field instance
*
* Attempt to find a field instance on the supplied argument clazz
* with the supplied name
and/or field type as argument fieldType.
* Searches all superclasses up to Object
.
*
* 查找字段实例
*
* 在给定的参数 clazz 上尝试使用提供的字段名称和/或属性类型为参数 fieldType 查找属性反射对象。
* 搜索所有超类直到 Object
。
*
*
* @param clazz Target class instance
* 目标类实例
* @param name the name of the field
* 字段名称
* @param fieldType the type of the field (maybe null
if name is specified)
* 字段的类型(如果指定了名称,则可能是 null
)
*
* @return the corresponding Field object, or null
if not found
* 相应的 Field 对象,如果未找到则为 null
*/
public static Field findField(final Class> clazz, final String name, final Class> fieldType) {
if (clazz == null) {
throw new IllegalArgumentException("Class must not be null");
}
if (name == null) {
throw new IllegalArgumentException("Name of the field must be specified");
}
Class> searchType = clazz;
while (!Object.class.equals(searchType) && searchType != null) {
try {
Field field = searchType.getDeclaredField(name);
if ((fieldType == null || fieldType.equals(field.getType()))) {
return field;
}
} catch (NoSuchFieldException ignored) {
}
searchType = searchType.getSuperclass();
}
return null;
}
/**
* Find method instance
*
* Attempt to find a method instance on the supplied argument clazz
* with the supplied name
.
* Searches all superclasses up to Object
.
*
* 查找方法实例
*
* 尝试使用提供的方法名称在提供的参数 clazz 上查找方法的反射实例对象。
* 搜索所有超类直到 Object
。
*
*
* @param clazz Target class instance
* 目标类实例
* @param name the name of the method
* 方法名称
*
* @return the Method object, or null
if none found
* Method 对象,如果没有找到则为 null
*/
public static Method findMethod(final Class> clazz, final String name) {
return findMethod(clazz, name, new Class[0]);
}
/**
* Find method instance
*
* Attempt to find a method instance on the supplied argument clazz
* with the supplied name
and parameter types.
* Searches all superclasses up to Object
.
*
* 查找方法实例
*
* 尝试使用提供的方法名称和参数类型数组在提供的参数 clazz 上查找方法的反射实例对象。
* 搜索所有超类直到 Object
。
*
*
* @param clazz Target class instance
* 目标类实例
* @param name the name of the method
* 方法名称
* @param paramTypes the parameter types of the method (maybe null
to indicate any signature)
* 方法的参数类型(可能是 null
来指示任何签名)
*
* @return the Method object, or null
if none found
* Method 对象,如果没有找到则为 null
*/
public static Method findMethod(final Class> clazz, final String name, final Class>[] paramTypes) {
if (clazz == null) {
throw new IllegalArgumentException("Class must not be null");
}
if (name == null) {
throw new IllegalArgumentException("Method name must not be null");
}
Class> searchType = clazz;
Class>[] paramClasses = ((paramTypes == null) ? new Class[0] : paramTypes);
while (!Object.class.equals(searchType) && searchType != null) {
try {
return searchType.isInterface()
? searchType.getMethod(name, paramClasses)
: searchType.getDeclaredMethod(name, paramClasses);
} catch (NoSuchMethodException ignored) {
}
searchType = searchType.getSuperclass();
}
return null;
}
/**
* Find getter method of given field name
* 查找给定属性的Getter方法实例
*
* @param fieldName Field name
* 属性名
* @param targetClass Target class instance
* 目标类实例
*
* @return the Method object, or null
if none found
* Method 对象,如果没有找到则为 null
*/
public static Method getterMethod(final String fieldName, final Class> targetClass) {
return findMethod(fieldName, targetClass, MethodType.Getter);
}
/**
* Find setter method of given field name
* 查找给定属性的Setter方法实例
*
* @param fieldName Field name
* 属性名
* @param targetClass Target class instance
* 目标类实例
*
* @return the Method object, or null
if none found
* Method 对象,如果没有找到则为 null
*/
public static Method setterMethod(final String fieldName, final Class> targetClass) {
return findMethod(fieldName, targetClass, MethodType.Setter);
}
/**
* Parse enumeration value string to enumeration instance
* 将枚举值字符串解析为枚举实例
*
* @param enumeration type class
* 枚举类
* @param enumClass enumeration type class
* 枚举类
* @param enumValue enumeration value string
* 枚举值字符串
*
* @return Parsed enumeration instance, or null
if none found
* 解析后的枚举实例,如果没有找到则为 null
*/
public static T parseEnum(final Class enumClass, final String enumValue) {
return Optional.ofNullable(findMethod(enumClass, "valueOf", new Class[]{String.class}))
.map(method -> {
try {
return enumClass.cast(invokeMethod(method, null, new Object[]{enumValue}));
} catch (Exception ignored) {
return null;
}
})
.orElse(null);
}
/**
*
* Set the field represented by the supplied argument field on
* the specified argument target to the specified argument value.
*
*
* In accordance with Field#set(Object, Object)
semantics, the new value is
* automatically unwrapped if the underlying field has a primitive type.
* Thrown exceptions are handled via a call to ReflectionUtils#handleReflectionException(Exception)
.
*
* 将指定参数 target 上提供的参数 field 表示的字段设置为参数 value。
*
* 根据 Field#set(Object, Object)
语义,如果基础字段具有原始类型,则新值会自动解包。
* 抛出的异常通过调用 ReflectionUtils#handleReflectionException(Exception)
进行处理。
*
* @see ReflectionUtils#handleReflectionException(Exception)
*
* @param field the field to set
* 要设置的字段
* @param target the target object on which to set the field
* 要设置字段的目标对象
* @param value the value to set; may be null
* 要设置的值;可能为null
*/
public static void setField(final Field field, final Object target, final Object value) {
try {
field.set(target, value);
} catch (IllegalAccessException ex) {
handleReflectionException(ex);
throw new IllegalStateException(
"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
}
}
/**
* Get the field represented by the supplied argument fieldName on the specified argument target.
*
* In accordance with Field#get(Object)
semantics, the returned value is
* automatically wrapped if the underlying field has a primitive type.
* Thrown exceptions are handled via a call to ReflectionUtils#handleReflectionException(Exception)
.
*
* 获取指定参数 target 上提供的参数 fieldName 表示的字段。
*
* 根据 Field#get(Object)
语义,如果底层字段具有原始类型,则返回的值会自动包装。
* 抛出的异常通过调用 ReflectionUtils#handleReflectionException(Exception)
进行处理。
*
* @see ReflectionUtils#handleReflectionException(Exception)
*
* @param fieldName the name of field to get
* 要获取的字段名称
* @param target the target object on which to get the field
* 要获取字段的目标对象
*
* @return the field's current value
* 该字段的当前值
*/
public static Object getFieldValue(final String fieldName, final Object target) {
if (fieldName == null || target == null) {
return null;
}
try {
Method getMethod = getterMethod(fieldName, target.getClass());
if (getMethod != null) {
return getMethod.invoke(target);
} else {
Field field = getFieldIfAvailable(target.getClass(), fieldName);
return ReflectionUtils.getFieldValue(field, target);
}
} catch (Exception ex) {
handleReflectionException(ex);
throw new IllegalStateException(
"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
}
}
/**
* Get the field represented by the supplied argument field on the specified argument target.
*
* In accordance with Field#get(Object)
semantics, the returned value is
* automatically wrapped if the underlying field has a primitive type.
* Thrown exceptions are handled via a call to ReflectionUtils#handleReflectionException(Exception)
.
*
* 获取指定参数 target 上提供的参数 field 表示的字段。
*
* 根据 Field#get(Object)
语义,如果底层字段具有原始类型,则返回的值会自动包装。
* 抛出的异常通过调用 ReflectionUtils#handleReflectionException(Exception)
进行处理。
*
* @see ReflectionUtils#handleReflectionException(Exception)
*
* @param field the field to get
* 要获取的字段
* @param target the target object on which to get the field
* 要获取字段的目标对象
*
* @return the field's current value
* 该字段的当前值
*/
public static Object getFieldValue(final Field field, final Object target) {
if (field == null || target == null) {
return null;
}
try {
makeAccessible(field);
return field.get(target);
} catch (IllegalAccessException ex) {
handleReflectionException(ex);
throw new IllegalStateException(
"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
}
}
/**
* Execute method object.
* 执行方法对象。
*
* @param methodName the method name
* 方法名称
* @param target the target object on which to execute the method
* 执行方法的目标对象
*
* @return the execute result value
* 执行结果值
*
* @throws IllegalArgumentException
* If method not found
* 如果方法未找到
*/
public static Object invokeMethod(final String methodName, final Object target)
throws IllegalArgumentException {
return invokeMethod(methodName, target, new Class[]{});
}
/**
* Invoke the specified method against the supplied target object with the supplied arguments.
*
* The target object can be null
when invoking a static method.
* Thrown exceptions are handled via a call to ReflectionUtils#handleReflectionException(Exception)
.
*
* 使用提供的参数针对提供的目标对象调用指定的方法
*
* 调用静态方法时,目标对象可以为 null
。
* 抛出的异常是通过调用 ReflectionUtils#handleReflectionException(Exception)
来处理的。
*
* @see ReflectionUtils#invokeMethod(java.lang.reflect.Method, Object, Object[])
* @see ReflectionUtils#handleReflectionException(Exception)
*
* @param methodName the method name
* 方法名称
* @param target the target object on which to execute the method
* 执行方法的目标对象
* @param paramClasses the parameter class array of the method
* 方法的参数类数组
* @param args the parameter object array of the method
* 方法的参数对象数组
*
* @return the execute result value
* 执行结果值
*
* @throws IllegalArgumentException
* If method not found
* 如果方法未找到
*/
public static Object invokeMethod(final String methodName, final Object target,
final Class>[] paramClasses, final Object... args)
throws IllegalArgumentException {
Class>[] parameterTypes = CollectionUtils.isEmpty(paramClasses) ? new Class[0] : paramClasses;
Object[] parameterValues = CollectionUtils.isEmpty(args) ? new Object[0] : args;
if (parameterValues.length != parameterTypes.length) {
throw new IllegalArgumentException("Arguments not matched! ");
}
Method method = findMethod(target.getClass(), methodName, parameterTypes);
if (method == null) {
throw new IllegalArgumentException("Method named : " + methodName + " does not exists");
}
ReflectionUtils.makeAccessible(method);
return invokeMethod(method, target, parameterValues);
}
/**
* Invoke the specified method against the supplied target object with no arguments.
*
* The target object can be null
when invoking a static method.
* Thrown exceptions are handled via a call to ReflectionUtils#handleReflectionException(Exception)
.
*
* 对提供的目标对象调用指定的方法 method(不带任何参数)。
*
* 调用静态方法时,目标对象可以为 null
。
* 抛出的异常是通过调用 ReflectionUtils#handleReflectionException(Exception)
来处理的。
*
* @see ReflectionUtils#invokeMethod(java.lang.reflect.Method, Object, Object[])
* @see ReflectionUtils#handleReflectionException(Exception)
*
* @param method the method to invoke
* 调用的方法
* @param target the target object on which to execute the method
* 执行方法的目标对象
*
* @return the execute result value
* 执行结果值
*/
public static Object invokeMethod(final Method method, final Object target) {
return invokeMethod(method, target, null);
}
/**
* Invoke the specified method against the supplied target object with the supplied arguments.
*
* The target object can be null
when invoking a static method.
* Thrown exceptions are handled via a call to ReflectionUtils#handleReflectionException(Exception)
.
*
* 使用提供的参数针对提供的目标对象调用指定的方法
*
* 调用静态方法时,目标对象可以为 null
。
* 抛出的异常是通过调用 ReflectionUtils#handleReflectionException(Exception)
来处理的。
*
* @see ReflectionUtils#invokeMethod(java.lang.reflect.Method, Object, Object[])
* @see ReflectionUtils#handleReflectionException(Exception)
*
* @param method the method to invoke
* 调用的方法
* @param target the target object on which to execute the method
* 执行方法的目标对象
* @param args the invocation arguments (maybe null
)
* 调用参数(可能null
)
*
* @return the execute result value
* 执行结果值
*/
public static Object invokeMethod(final Method method, final Object target, final Object[] args) {
try {
return method.invoke(target, args);
} catch (Exception ex) {
handleReflectionException(ex);
}
throw new IllegalStateException("Should never get here");
}
/**
* Handle the given reflection exception.
*
* Should only be called if no checked exception is expected to be thrown by the target method.
* Throws the underlying RuntimeException or Error in case of an
* InvocationTargetException with such a root cause.
* Throw an IllegalStateException with an appropriate message else.
*
* 处理给定的反射异常。
*
* 仅当目标方法预计不会引发已检查异常时才应调用。
* 如果出现具有此类根本原因的 InspirationTargetException,则抛出基础 RuntimeException 或 Error。
* 抛出 IllegalStateException 并附加适当的消息。
*
*
* @param ex the reflection exception to handle
* 要处理的反射异常
*/
public static void handleReflectionException(final Exception ex) {
if (ex instanceof NoSuchMethodException) {
throw new IllegalStateException("Method not found: " + ex.getMessage());
}
if (ex instanceof IllegalAccessException) {
throw new IllegalStateException("Could not access method: " + ex.getMessage());
}
if (ex instanceof InvocationTargetException) {
handleInvocationTargetException((InvocationTargetException) ex);
}
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
handleUnexpectedException(ex);
}
/**
* Handle the given invocation exception.
*
* Should only be called if no checked exception is expected to be thrown by the target method.
* Throws the underlying RuntimeException or Error in case of such a root cause.
* Throws an IllegalStateException else.
*
* 处理给定的调用异常。
*
* 仅当目标方法预计不会引发已检查异常时才应调用。
* 如果出现此类根本原因,则抛出底层 RuntimeException 或 Error。
* 否则抛出 IllegalStateException。
*
*
* @param ex the invocation exception to handle
* 要处理的调用异常
*/
public static void handleInvocationTargetException(final InvocationTargetException ex) {
rethrowRuntimeException(ex.getTargetException());
}
/**
* Rethrow the given argument ex
*
* which is presumably the target exception of an InvocationTargetException
.
* Should only be called if no checked exception is expected to be thrown by the target method.
* Rethrows the underlying exception cast to an RuntimeException
or Error
if appropriate;
* otherwise, throws an IllegalStateException
.
*
* 重新抛出给定的参数 ex
*
* 这可能是 InvocationTargetException
的目标异常。
* 仅当目标方法预计不会引发已检查异常时才应调用。
* 如果适用,重新抛出底层异常转换为 RuntimeException
或 Error
;
* 否则,抛出一个IllegalStateException
。
*
*
* @param ex the exception to rethrow
* 要重新抛出的异常
*
* @throws RuntimeException
* the rethrown exception (in case of a checked exception)
* 重新抛出的异常(在检查异常的情况下)
*/
public static void rethrowRuntimeException(final Throwable ex) {
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
if (ex instanceof Error) {
throw (Error) ex;
}
handleUnexpectedException(ex);
}
/**
* Rethrow the given argument ex
*
* which is presumably the target exception of an InvocationTargetException
.
* Should only be called if no checked exception is expected to be thrown by the target method.
* Rethrows the underlying exception cast to an Exception
or Error
if appropriate;
* otherwise, throws an IllegalStateException
.
*
* 重新抛出给定的参数 ex
*
* 这可能是 InvocationTargetException
的目标异常。
* 仅当目标方法预计不会引发已检查异常时才应调用。
* 如果适用,重新抛出底层异常转换为 Exception
或 Error
;
* 否则,抛出一个IllegalStateException
。
*
*
* @param ex the exception to rethrow
* 要重新抛出的异常
*
* @throws Exception
* the rethrown exception (in case of a checked exception)
* 重新抛出的异常(在检查异常的情况下)
*/
public static void rethrowException(final Throwable ex) throws Exception {
if (ex instanceof Exception) {
throw (Exception) ex;
}
if (ex instanceof Error) {
throw (Error) ex;
}
handleUnexpectedException(ex);
}
/**
*
* Determine whether the given method explicitly declares the given exception
* or one of its superclasses, which means that an exception to that type
* can be propagated as-is within a reflective invocation.
*
* 确定给定方法是否显式声明给定异常或其超类之一,这意味着该类型的异常可以在反射调用中按原样传播。
*
* @param method the declaring method
* 声明方法
* @param exceptionType the exception to throw
* 要抛出的异常
*
* @return true
if the exception can be thrown as-is; false
if it needs to be wrapped
* 如果异常可以按原样抛出则返回true
;如果需要包装则返回false
*/
public static boolean declaresException(final Method method, final Class> exceptionType) {
if (method == null) {
throw new IllegalArgumentException("Method must not be null");
}
Class>[] declaredExceptions = method.getExceptionTypes();
for (Class> declaredException : declaredExceptions) {
if (declaredException.isAssignableFrom(exceptionType)) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
/**
* Determine whether the given field/method is a "public" member.
* 确定给定的字段/方法是否是“公共”成员。
*
* @param member the field/method to check
* 要检查的字段/方法
*
* @return is a "public" member.
* 是一个“公共”成员。
*/
public static boolean publicMember(final Member member) {
return Optional.ofNullable(member)
.map(checkMember -> Modifier.isPublic(checkMember.getModifiers()))
.orElse(Boolean.FALSE);
}
/**
* Determine whether the given field/method is a "protected" member.
* 确定给定的字段/方法是否是“保护”成员。
*
* @param member the field/method to check
* 要检查的字段/方法
*
* @return is a "protected" member.
* 是一个“保护”成员。
*/
public static boolean protectedMember(final Member member) {
return Optional.ofNullable(member)
.map(checkMember -> Modifier.isProtected(checkMember.getModifiers()))
.orElse(Boolean.FALSE);
}
/**
* Determine whether the given field/method is a "private" member.
* 确定给定的字段/方法是否是“私有”成员。
*
* @param member the field/method to check
* 要检查的字段/方法
*
* @return is a "private" member.
* 是一个“私有”成员。
*/
public static boolean privateMember(final Member member) {
return Optional.ofNullable(member)
.map(checkMember -> Modifier.isPrivate(checkMember.getModifiers()))
.orElse(Boolean.FALSE);
}
/**
* Determine whether the given field/method is a "static" member.
* 确定给定的字段/方法是否是“静态”成员。
*
* @param member the field/method to check
* 要检查的字段/方法
*
* @return is a "static" member.
* 是一个“静态”成员。
*/
public static boolean staticMember(final Member member) {
return Optional.ofNullable(member)
.map(checkMember -> Modifier.isStatic(checkMember.getModifiers()))
.orElse(Boolean.FALSE);
}
/**
* Determine whether the given field/method is a "final" member.
* 确定给定的字段/方法是否是“最终”成员。
*
* @param member the field/method to check
* 要检查的字段/方法
*
* @return is a "final" member.
* 是一个“最终”成员。
*/
public static boolean finalMember(final Member member) {
return Optional.ofNullable(member)
.map(checkMember -> Modifier.isFinal(checkMember.getModifiers()))
.orElse(Boolean.FALSE);
}
/**
* Determine whether the given field/method is a "public static final" member.
* 确定给定的字段/方法是否是“公开静态最终”成员。
*
* @param member the field/method to check
* 要检查的字段/方法
*
* @return is a "public static final" member.
* 是一个“公开静态最终”成员。
*/
public static boolean isPublicStaticFinal(final Member member) {
return publicMember(member) && staticMember(member) && finalMember(member);
}
/**
* Make the given field accessible, explicitly setting it accessible if necessary.
*
* The setAccessible(true)
method is only called when actually necessary,
* to avoid unnecessary conflicts with a JVM SecurityManager (if active).
*
* 使给定字段可访问,必要时明确将其设置为可访问。
*
* setAccessible(true)
方法仅在实际需要时调用,以避免与 JVM SecurityManager(如果处于活动状态)发生不必要的冲突。
*
* @see java.lang.reflect.Field#setAccessible
*
* @param field the field to make accessible
* 使可访问的字段/span>
*/
public static void makeAccessible(final Field field) {
if (privateMember(field) || protectedMember(field) ||
!Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
field.setAccessible(Boolean.TRUE);
}
}
/**
* Make the given method accessible, explicitly setting it accessible if necessary.
*
* The setAccessible(true)
method is only called when actually necessary,
* to avoid unnecessary conflicts with a JVM SecurityManager (if active).
*
* 使给定方法可访问,必要时明确将其设置为可访问。
*
* setAccessible(true)
方法仅在实际需要时调用,以避免与 JVM SecurityManager(如果处于活动状态)发生不必要的冲突。
*
* @see java.lang.reflect.Method#setAccessible
*
* @param method the method to make accessible
* 使可访问的方法
*/
public static void makeAccessible(final Method method) {
if (privateMember(method) || protectedMember(method) ||
!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
method.setAccessible(true);
}
}
/**
* Make the given constructor accessible, explicitly setting it accessible if necessary.
*
* The setAccessible(true)
method is only called when actually necessary,
* to avoid unnecessary conflicts with a JVM SecurityManager (if active).
*
* 使给定构造方法可访问,必要时明确将其设置为可访问。
*
* setAccessible(true)
方法仅在实际需要时调用,以避免与 JVM SecurityManager(如果处于活动状态)发生不必要的冲突。
*
* @see java.lang.reflect.Constructor#setAccessible
*
* @param ctor the constructor to make accessible
* 使可访问的构造方法
*/
public static void makeAccessible(final Constructor> ctor) {
if (!Modifier.isPublic(ctor.getModifiers()) ||
!Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) {
ctor.setAccessible(true);
}
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
*
* @return all non-static declared fields list, or empty list if given class is null
* 所有声明的非静态属性列表,如果给定的类为 null
则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz) {
return getAllDeclaredFields(clazz, Boolean.FALSE);
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
* @param memberFilter Field filter (maybe null
for process callback at all fields)
* 属性过滤器(当为null
时为所有的属性执行回调)
*
* @return all non-static declared fields list, or empty list if given class is null
* 所有声明的非静态属性列表,如果给定的类为 null
则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz, final MemberFilter memberFilter) {
return getAllDeclaredFields(clazz, Boolean.FALSE, memberFilter);
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
*
* @return all non-static declared fields list, or empty list if given class is null
* 所有声明的非静态属性列表,如果给定的类为 null
则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz, final boolean parseParent) {
return getAllDeclaredFields(clazz, parseParent, (Class extends Annotation>[]) null);
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param annotations
* Parent class annotation arrays, only using for parameter parseParent
* is Boolean.TRUE
.
* Parent class will parsed which class was annotation with anyone of annotation arrays
* or annotation arrays is null
or empty.
*
*
* 父类的注解数组,仅用于参数parseParent为Boolean.TRUE
时。
* 父类必须使用注解数组中的任一注解进行标注,或注解数组为null
或空数组时,才会解析
*
*
* @return all non-static declared fields list, or empty list if given class is null
* 所有声明的非静态属性列表,如果给定的类为 null
则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz, final boolean parseParent,
final Class extends Annotation>[] annotations) {
return getAllDeclaredFields(clazz, parseParent, annotations, NON_STATIC_FINAL_MEMBERS);
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param memberFilter Field filter (maybe null
for process callback at all fields)
* 属性过滤器(当为null
时为所有的属性执行回调)
*
* @return all non-static declared fields list, or empty list if given class is null
* 所有声明的非静态属性列表,如果给定的类为 null
则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz, final boolean parseParent,
final MemberFilter memberFilter) {
return getAllDeclaredFields(clazz, parseParent, (ClassFilter) null, memberFilter);
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param annotations
* Parent class annotation arrays, only using for parameter parseParent
* is Boolean.TRUE
.
* Parent class will parsed which class was annotation with anyone of annotation arrays
* or annotation arrays is null
or empty.
*
*
* 父类的注解数组,仅用于参数parseParent为Boolean.TRUE
时。
* 父类必须使用注解数组中的任一注解进行标注,或注解数组为null
或空数组时,才会解析
*
* @param memberFilter Field filter (maybe null
for process callback at all fields)
* 属性过滤器(当为null
时为所有的属性执行回调)
*
* @return all non-static declared fields list, or empty list if given class is null
* 所有声明的非静态属性列表,如果给定的类为 null
则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz, final boolean parseParent,
final Class extends Annotation>[] annotations,
final MemberFilter memberFilter) {
return getAllDeclaredFields(clazz, parseParent, new AnnotationClassFilter(annotations), memberFilter);
}
/**
* Gets all non-static declared fields from given class.
* 获取给定类的所有声明的非静态属性。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param classFilter Parent class filter (maybe null
for process all parent class)
* 父类过滤器(当为null
时处理所有父类)
* @param memberFilter Field filter (maybe null
for process callback at all fields)
* 属性过滤器(当为null
时为所有的属性执行回调)
*
* @return all non-static declared fields list, or empty list if given class is null
or an error occurs
* 所有声明的非静态属性列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredFields(Class> clazz, final boolean parseParent,
final ClassFilter classFilter, final MemberFilter memberFilter) {
try {
List fieldList = new ArrayList<>();
doWithFields(clazz, fieldList::add, parseParent, classFilter, memberFilter);
return fieldList;
} catch (IllegalArgumentException | IllegalAccessException e) {
LOGGER.error("Fields_Retrieve_Reflection_Error");
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Stack_Message_Error", e);
}
return Collections.emptyList();
}
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz) {
return getAllDeclaredMethods(clazz, Boolean.FALSE, (Class extends Annotation>[]) null, null);
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
* @param memberFilter Method filter (maybe null
for process callback at all fields)
* 方法过滤器(当为null
时为所有的属性执行回调)
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz, final MemberFilter memberFilter) {
return getAllDeclaredMethods(clazz, Boolean.FALSE, memberFilter);
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz, final boolean parseParent) {
return getAllDeclaredMethods(clazz, parseParent, (Class extends Annotation>[]) null, null);
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param annotations
* Parent class annotation arrays, only using for parameter parseParent
* is Boolean.TRUE
.
* Parent class will parsed which class was annotation with anyone of annotation arrays
* or annotation arrays is null
or empty.
*
*
* 父类的注解数组,仅用于参数parseParent为Boolean.TRUE
时。
* 父类必须使用注解数组中的任一注解进行标注,或注解数组为null
或空数组时,才会解析
*
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz, final boolean parseParent,
final Class extends Annotation>[] annotations) {
return getAllDeclaredMethods(clazz, parseParent, new AnnotationClassFilter(annotations), null);
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param memberFilter Method filter (maybe null
for process callback at all fields)
* 方法过滤器(当为null
时为所有的属性执行回调)
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz, final boolean parseParent,
final MemberFilter memberFilter) {
return getAllDeclaredMethods(clazz, parseParent, (ClassFilter) null, memberFilter);
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param annotations
* Parent class annotation arrays, only using for parameter parseParent
* is Boolean.TRUE
.
* Parent class will parsed which class was annotation with anyone of annotation arrays
* or annotation arrays is null
or empty.
*
*
* 父类的注解数组,仅用于参数parseParent为Boolean.TRUE
时。
* 父类必须使用注解数组中的任一注解进行标注,或注解数组为null
或空数组时,才会解析
*
* @param memberFilter Method filter (maybe null
for process callback at all fields)
* 方法过滤器(当为null
时为所有的属性执行回调)
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz, final boolean parseParent,
final Class extends Annotation>[] annotations,
final MemberFilter memberFilter) {
return getAllDeclaredMethods(clazz, parseParent, new AnnotationClassFilter(annotations), memberFilter);
}
/**
* Get all declared methods on the given class and all superclasses. Leaf class methods are included first.
* 获取给定类和所有超类的所有声明方法。首先包含叶类方法。
*
* @param clazz given class
* 给定的类
* @param parseParent Retrieve fields from parent class
* 获取父类的非静态属性
* @param classFilter Parent class filter (maybe null
for process all parent class)
* 父类过滤器(当为null
时处理所有父类)
* @param memberFilter Method filter (maybe null
for process callback at all fields)
* 方法过滤器(当为null
时为所有的属性执行回调)
*
* @return All declared method list, or empty list if given class is null
or an error occurs
* 所有声明的方法列表,如果给定的类为 null
或出现异常则返回空列表
*/
public static List getAllDeclaredMethods(Class> clazz, final boolean parseParent,
final ClassFilter classFilter, final MemberFilter memberFilter) {
try {
final List methodList = new ArrayList<>();
doWithMethods(clazz, methodList::add, parseParent, classFilter, memberFilter);
return methodList;
} catch (IllegalArgumentException e) {
LOGGER.error("Methods_Retrieve_Reflection_Error");
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Stack_Message_Error", e);
}
return Collections.emptyList();
}
}
/**
* Shallow copy from argument src to dest
*
* Given the source object and the destination, which must be the same class
* or a subclass, copy all fields, including inherited fields.
* Designed to work on objects with public no-arg constructors.
*
* 从参数 src 浅复制到 dest
*
* 给定源对象和目标(必须是同一类或子类),复制所有字段,包括继承的字段。
* 设计用于处理具有公共无参数构造函数的对象。
*
*
* @param src source object
* 源对象
* @param dest target object
* 目标对象
*
* @throws IllegalArgumentException
* if the arguments are incompatible
* 如果参数不兼容
*/
public static void shallowCopyFieldState(final Object src, final Object dest)
throws IllegalArgumentException, IllegalAccessException {
if (src == null) {
throw new IllegalArgumentException("Source for field copy cannot be null");
}
if (dest == null) {
throw new IllegalArgumentException("Destination for field copy cannot be null");
}
if (!src.getClass().isAssignableFrom(dest.getClass())) {
throw new IllegalArgumentException("Destination class [" + dest.getClass().getName() +
"] must be same or subclass as source class [" + src.getClass().getName() + "]");
}
doWithFields(src.getClass(), field -> {
makeAccessible(field);
Object srcValue = field.get(src);
field.set(dest, srcValue);
}, Boolean.TRUE, null, NON_STATIC_FINAL_MEMBERS);
}
/**
* Retrieve the field object named by given argument fieldName on the given class and all superclasses.
* 检索给定类和所有超类上由给定参数 fieldName 命名的属性对象。
*
* @param clazz given class
* 给定的类
* @param fieldName field name
* 属性名
*
* @return Retrieve the field object or null
if not exists
* 检索到的属性对象,如果不存在则返回 null
*/
public static Field getFieldIfAvailable(final Class> clazz, final String fieldName) {
if (clazz == null) {
return null;
}
try {
return clazz.getDeclaredField(fieldName);
} catch (Exception e) {
return getFieldIfAvailable(clazz.getSuperclass(), fieldName);
}
}
/**
* Set the field values by given argument parameterMap(key is field name, value is field value) to the argument target instance.
* 通过给定的参数 parameterMap (键是属性名称,值是属性值)将数据设置到参数 target 实例。
*
* @param target Target instance
* 目标实例对象
* @param parameterMap field data map
* 属性数据映射表
*/
public static void setField(final Object target, final Map parameterMap) {
if (target == null || parameterMap == null) {
return;
}
parameterMap.forEach((key, value) -> {
Object fieldValue;
if (value.getClass().isArray()) {
if (((Object[]) value).length == 1) {
fieldValue = ((Object[]) value)[0];
} else {
fieldValue = value;
}
} else {
fieldValue = value;
}
setField(key, target, fieldValue);
});
}
/**
* Set the field value by given argument fieldName to the argument target instance.
* 通过给定的参数 fieldName 找到参数 target 实例中的属性对象,并将属性值设置为参数 value 值。
*
* @param fieldName field name
* 属性名
* @param target the target object on which to set the field
* 要设置字段的目标对象
* @param value the value to set; may be null
* 要设置的值;可能为null
*/
public static void setField(final String fieldName, final Object target, final Object value) {
try {
Method setMethod = setterMethod(fieldName, target.getClass());
if (setMethod != null) {
makeAccessible(setMethod);
setMethod.invoke(target, value);
} else {
Field field = getFieldIfAvailable(target.getClass(), fieldName);
if (field != null) {
makeAccessible(field);
setField(field, target, value);
}
}
} catch (Exception e) {
if (ReflectionUtils.LOGGER.isDebugEnabled()) {
ReflectionUtils.LOGGER.debug("Set_Value_Reflection_Error", e, fieldName,
Optional.ofNullable(value)
.map(val -> val.getClass().getName()).orElse(Globals.DEFAULT_VALUE_STRING));
}
}
}
/**
* Callback interface invoked on each method in the hierarchy.
* 在层次结构中的每个方法上调用回调接口。
*
* @author Steven Wee [email protected]
* @version $Revision: 1.0.0 $ $Date: Jan 15, 2010 10:27:42 $
*/
public interface MethodCallback {
/**
*
* Perform an operation using the given method.
* 使用给定方法执行操作。
*
* @param method the method to operate on
* 要操作的方法
*
* @throws IllegalArgumentException
* If an error occurs when invoke doWith
* 如果调用doWith时出现错误
* @see java.lang.IllegalArgumentException
*/
void doWith(Method method) throws IllegalArgumentException;
}
/**
* Callback interface invoked on each field in the hierarchy.
* 在层次结构中的每个字段上调用回调接口。
*
* @author Steven Wee [email protected]
* @version $Revision: 1.0.0 $ $Date: Jan 15, 2010 10:29:21 $
*/
public interface FieldCallback {
/**
* Perform an operation using the given field.
* 使用给定属性执行操作。
*
* @param field the field to operate on
* 要操作的属性
*
* @throws IllegalArgumentException
* If an error occurs when invoke doWith
* 如果调用doWith时出现错误
* @see java.lang.IllegalArgumentException
* @throws IllegalAccessException
* If an error occurs when invoke doWith
* 如果调用doWith时出现错误
* @see java.lang.IllegalAccessException
*/
void doWith(Field field) throws IllegalArgumentException, IllegalAccessException;
}
/**
* Callback optionally used to filter members to be operated on by a member callback.
* 回调可选地用于过滤要由成员回调操作的成员。
*
* @author Steven Wee [email protected]
* @version $Revision: 1.0.0 $ $Date: Jan 15, 2010 10:30:15 $
*/
public interface MemberFilter {
/**
* Determine whether the given member matches.
* 确定给定成员是否匹配。
*
* @param member the member to check
* 要检查的成员
*
* @return check result
* 检查结果
*/
boolean matches(final Member member);
}
/**
* Callback optionally used to filter classes to be operated on super class.
* 回调可选地用于过滤要在超类上操作的类。
*
* @author Steven Wee [email protected]
* @version $Revision: 1.0.0 $ $Date: Jan 15, 2010 10:31:08 $
*/
public interface ClassFilter {
/**
* Determine whether the given class matches.
* 确定给定类是否匹配。
*
* @param clazz the class to check
* 要检查的类
*
* @return check result
* 检查结果
*/
boolean matches(Class> clazz);
}
/**
* Pre-build ClassFilter that matches classes was annotation by anyone of given Annotation class array.
* 匹配类的预构建 ClassFilter 是由给定 Annotation 类数组的任何一个进行注释的。
*
* @author Steven Wee [email protected]
* @version $Revision: 1.0.0 $ $Date: Jan 15, 2010 10:33:28 $
*/
public static final class AnnotationClassFilter implements ClassFilter {
/**
* Annotation class array
* Annotation 类数组
*/
private final List> annotations;
/**
* Constructor for AnnotationClassFilter
* 注解类过滤器的构造方法
*
* @param annotations Annotation class array
* Annotation 类数组
*/
public AnnotationClassFilter(final Class extends Annotation>[] annotations) {
this.annotations = annotations == null ? Collections.emptyList() : Arrays.asList(annotations);
}
/**
* (Non-Javadoc)
* @see ClassFilter#matches(Class)
*/
@Override
public boolean matches(final Class> clazz) {
if (clazz == null) {
return Boolean.FALSE;
}
if (this.annotations.isEmpty()) {
return Boolean.TRUE;
}
return this.annotations.stream().anyMatch(clazz::isAnnotationPresent);
}
}
/**
* Pre-built MemberFilter that matches all non-static, non-final members.
* 预构建的 MemberFilter 匹配所有非静态、非最终成员。
*/
public static final MemberFilter NON_STATIC_FINAL_MEMBERS = member -> !(staticMember(member) || finalMember(member));
/**
* Throws an IllegalStateException with the given exception as root cause.
* 抛出异常 IllegalStateException,并将给定异常作为根本原因。
*
* @param ex the unexpected exception
* 意外的异常
*/
private static void handleUnexpectedException(final Throwable ex) {
// Needs to avoid the chained constructor for JDK 1.4 compatibility.
throw new IllegalStateException("Unexpected exception thrown", ex);
}
/**
* Find method
* 查找方法实例
*
* @param fieldName Field name
* 属性名
* @param targetClass Target class instance
* 目标类实例
* @param methodType Method type
* 方法类型
*
* @return the Method object, or null
if none found
* Method 对象,如果没有找到则为 null
*/
private static Method findMethod(final String fieldName, final Class> targetClass, final MethodType methodType) {
Field field = ReflectionUtils.getFieldIfAvailable(targetClass, fieldName);
if (field == null) {
return null;
}
return findMethod(targetClass, methodName(field, methodType),
MethodType.Setter.equals(methodType) ? new Class>[]{field.getType()} : new Class[0]);
}
/**
* Generate method name
* 生成方法名称
*
* @param field Field instance
* 属性实例对象
* @param methodType Method type
* 方法类型
*
* @return Generated method name
* 生成的方法名称
*/
private static String methodName(final Field field, final MethodType methodType) {
StringBuilder methodName = new StringBuilder();
switch (methodType) {
case Getter:
if (boolean.class.equals(field.getType())) {
methodName.append("is");
} else {
methodName.append("get");
}
break;
case Setter:
methodName.append("set");
break;
default:
return Globals.DEFAULT_VALUE_STRING;
}
String fieldName = field.getName();
methodName.append(fieldName.substring(0, 1).toUpperCase()).append(fieldName.substring(1));
return methodName.toString();
}
/**
* Invoke the given callback on all fields in the target class, going up the class hierarchy to get all declared fields.
* 对目标类中的所有字段调用给定的回调,沿类层次结构向上获取所有声明的字段。
*
* @param targetClass Target class
* 目标类
* @param callback given callback
* 给定的回调
* @param doParent Process parent class
* 处理父类
* @param classFilter Parent class filter (maybe null
for process all parent class)
* 父类过滤器(当为null
时处理所有父类)
* @param memberFilter Field filter (maybe null
for process callback at all fields)
* 属性过滤器(当为null
时为所有的属性执行回调)
*
* @throws IllegalArgumentException
* If an error occurs when invoke callback
* 如果调用回调时出现错误
*
* @throws IllegalAccessException
* If an error occurs when invoke callback
* 如果调用回调时出现错误
*
*/
private static void doWithFields(Class> targetClass, final FieldCallback callback, final boolean doParent,
final ClassFilter classFilter, final MemberFilter memberFilter)
throws IllegalArgumentException, IllegalAccessException {
// Keep backing up the inheritance hierarchy.
do {
// Copy each field declared on this class unless it's static or file.
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
// Skip static and final fields.
if (memberFilter == null || memberFilter.matches(field)) {
callback.doWith(field);
}
}
if (doParent) {
if (classFilter == null) {
targetClass = targetClass.getSuperclass();
} else {
do {
targetClass = targetClass.getSuperclass();
} while (targetClass != null && !classFilter.matches(targetClass));
}
} else {
break;
}
}
while (targetClass != null && !Object.class.equals(targetClass));
}
/**
* Perform the given callback operation on all matching methods of the given class and superclasses.
*
* The same named method occurring on subclass and superclass will appear twice,
* unless excluded by the specified argument memberFilter.
*
* 对给定类和超类的所有匹配方法执行给定的回调操作。
* 子类和超类上出现的相同命名方法将出现两次,除非被指定的参数 memberFilter 排除
*
* @param targetClass Target class
* 目标类
* @param callback given callback
* 给定的回调
* @param doParent Process parent class
* 处理父类
* @param classFilter Parent class filter (maybe null
for process all parent class)
* 父类过滤器(当为null
时处理所有父类)
* @param memberFilter Field filter (maybe null
for process callback at all fields)
* 属性过滤器(当为null
时为所有的属性执行回调)
*
* @throws IllegalArgumentException
* If an error occurs when invoke callback
* 如果调用回调时出现错误
*/
private static void doWithMethods(Class> targetClass, final MethodCallback callback, final boolean doParent,
final ClassFilter classFilter, final MemberFilter memberFilter)
throws IllegalArgumentException {
// Keep backing up the inheritance hierarchy.
do {
for (Method method : targetClass.getDeclaredMethods()) {
if (memberFilter == null || memberFilter.matches(method)) {
callback.doWith(method);
}
}
if (doParent) {
if (classFilter == null) {
targetClass = targetClass.getSuperclass();
} else {
do {
targetClass = targetClass.getSuperclass();
} while (targetClass != null && !classFilter.matches(targetClass));
}
} else {
break;
}
}
while (targetClass != null);
}
/**
* Enumeration of method type
* 方法类型的枚举
*/
private enum MethodType {
Getter, Setter
}
}