|
|
|
@ -483,6 +483,7 @@ public abstract class ReflectionUtils { |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param mc the callback to invoke for each method |
|
|
|
* @param mc the callback to invoke for each method |
|
|
|
* @since 4.2 |
|
|
|
* @since 4.2 |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
* @see #doWithMethods |
|
|
|
* @see #doWithMethods |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) { |
|
|
|
public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) { |
|
|
|
@ -504,6 +505,7 @@ public abstract class ReflectionUtils { |
|
|
|
* twice, unless excluded by a {@link MethodFilter}. |
|
|
|
* twice, unless excluded by a {@link MethodFilter}. |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param mc the callback to invoke for each method |
|
|
|
* @param mc the callback to invoke for each method |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
* @see #doWithMethods(Class, MethodCallback, MethodFilter) |
|
|
|
* @see #doWithMethods(Class, MethodCallback, MethodFilter) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void doWithMethods(Class<?> clazz, MethodCallback mc) { |
|
|
|
public static void doWithMethods(Class<?> clazz, MethodCallback mc) { |
|
|
|
@ -518,6 +520,7 @@ public abstract class ReflectionUtils { |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param mc the callback to invoke for each method |
|
|
|
* @param mc the callback to invoke for each method |
|
|
|
* @param mf the filter that determines the methods to apply the callback to |
|
|
|
* @param mf the filter that determines the methods to apply the callback to |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) { |
|
|
|
public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) { |
|
|
|
// Keep backing up the inheritance hierarchy.
|
|
|
|
// Keep backing up the inheritance hierarchy.
|
|
|
|
@ -547,6 +550,7 @@ public abstract class ReflectionUtils { |
|
|
|
* Get all declared methods on the leaf class and all superclasses. |
|
|
|
* Get all declared methods on the leaf class and all superclasses. |
|
|
|
* Leaf class methods are included first. |
|
|
|
* Leaf class methods are included first. |
|
|
|
* @param leafClass the class to introspect |
|
|
|
* @param leafClass the class to introspect |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Method[] getAllDeclaredMethods(Class<?> leafClass) { |
|
|
|
public static Method[] getAllDeclaredMethods(Class<?> leafClass) { |
|
|
|
final List<Method> methods = new ArrayList<Method>(32); |
|
|
|
final List<Method> methods = new ArrayList<Method>(32); |
|
|
|
@ -564,6 +568,7 @@ public abstract class ReflectionUtils { |
|
|
|
* Leaf class methods are included first and while traversing the superclass hierarchy |
|
|
|
* Leaf class methods are included first and while traversing the superclass hierarchy |
|
|
|
* any methods found with signatures matching a method already included are filtered out. |
|
|
|
* any methods found with signatures matching a method already included are filtered out. |
|
|
|
* @param leafClass the class to introspect |
|
|
|
* @param leafClass the class to introspect |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) { |
|
|
|
public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) { |
|
|
|
final List<Method> methods = new ArrayList<Method>(32); |
|
|
|
final List<Method> methods = new ArrayList<Method>(32); |
|
|
|
@ -604,26 +609,33 @@ public abstract class ReflectionUtils { |
|
|
|
* interfaces, since those are effectively to be treated just like declared methods. |
|
|
|
* interfaces, since those are effectively to be treated just like declared methods. |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @return the cached array of methods |
|
|
|
* @return the cached array of methods |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
* @see Class#getDeclaredMethods() |
|
|
|
* @see Class#getDeclaredMethods() |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private static Method[] getDeclaredMethods(Class<?> clazz) { |
|
|
|
private static Method[] getDeclaredMethods(Class<?> clazz) { |
|
|
|
Method[] result = declaredMethodsCache.get(clazz); |
|
|
|
Method[] result = declaredMethodsCache.get(clazz); |
|
|
|
if (result == null) { |
|
|
|
if (result == null) { |
|
|
|
Method[] declaredMethods = clazz.getDeclaredMethods(); |
|
|
|
try { |
|
|
|
List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz); |
|
|
|
Method[] declaredMethods = clazz.getDeclaredMethods(); |
|
|
|
if (defaultMethods != null) { |
|
|
|
List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz); |
|
|
|
result = new Method[declaredMethods.length + defaultMethods.size()]; |
|
|
|
if (defaultMethods != null) { |
|
|
|
System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length); |
|
|
|
result = new Method[declaredMethods.length + defaultMethods.size()]; |
|
|
|
int index = declaredMethods.length; |
|
|
|
System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length); |
|
|
|
for (Method defaultMethod : defaultMethods) { |
|
|
|
int index = declaredMethods.length; |
|
|
|
result[index] = defaultMethod; |
|
|
|
for (Method defaultMethod : defaultMethods) { |
|
|
|
index++; |
|
|
|
result[index] = defaultMethod; |
|
|
|
|
|
|
|
index++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
result = declaredMethods; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result)); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
catch (Throwable ex) { |
|
|
|
result = declaredMethods; |
|
|
|
throw new IllegalStateException("Failed to introspect Class [" + clazz + |
|
|
|
|
|
|
|
"] from ClassLoader [" + clazz.getClassLoader() + "]", ex); |
|
|
|
} |
|
|
|
} |
|
|
|
declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -649,6 +661,7 @@ public abstract class ReflectionUtils { |
|
|
|
* @param clazz the target class to analyze |
|
|
|
* @param clazz the target class to analyze |
|
|
|
* @param fc the callback to invoke for each field |
|
|
|
* @param fc the callback to invoke for each field |
|
|
|
* @since 4.2 |
|
|
|
* @since 4.2 |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
* @see #doWithFields |
|
|
|
* @see #doWithFields |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) { |
|
|
|
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) { |
|
|
|
@ -667,6 +680,7 @@ public abstract class ReflectionUtils { |
|
|
|
* class hierarchy to get all declared fields. |
|
|
|
* class hierarchy to get all declared fields. |
|
|
|
* @param clazz the target class to analyze |
|
|
|
* @param clazz the target class to analyze |
|
|
|
* @param fc the callback to invoke for each field |
|
|
|
* @param fc the callback to invoke for each field |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void doWithFields(Class<?> clazz, FieldCallback fc) { |
|
|
|
public static void doWithFields(Class<?> clazz, FieldCallback fc) { |
|
|
|
doWithFields(clazz, fc, null); |
|
|
|
doWithFields(clazz, fc, null); |
|
|
|
@ -678,6 +692,7 @@ public abstract class ReflectionUtils { |
|
|
|
* @param clazz the target class to analyze |
|
|
|
* @param clazz the target class to analyze |
|
|
|
* @param fc the callback to invoke for each field |
|
|
|
* @param fc the callback to invoke for each field |
|
|
|
* @param ff the filter that determines the fields to apply the callback to |
|
|
|
* @param ff the filter that determines the fields to apply the callback to |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff) { |
|
|
|
public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff) { |
|
|
|
// Keep backing up the inheritance hierarchy.
|
|
|
|
// Keep backing up the inheritance hierarchy.
|
|
|
|
@ -705,13 +720,20 @@ public abstract class ReflectionUtils { |
|
|
|
* in order to avoid the JVM's SecurityManager check and defensive array copying. |
|
|
|
* in order to avoid the JVM's SecurityManager check and defensive array copying. |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @param clazz the class to introspect |
|
|
|
* @return the cached array of fields |
|
|
|
* @return the cached array of fields |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
* @see Class#getDeclaredFields() |
|
|
|
* @see Class#getDeclaredFields() |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private static Field[] getDeclaredFields(Class<?> clazz) { |
|
|
|
private static Field[] getDeclaredFields(Class<?> clazz) { |
|
|
|
Field[] result = declaredFieldsCache.get(clazz); |
|
|
|
Field[] result = declaredFieldsCache.get(clazz); |
|
|
|
if (result == null) { |
|
|
|
if (result == null) { |
|
|
|
result = clazz.getDeclaredFields(); |
|
|
|
try { |
|
|
|
declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result)); |
|
|
|
result = clazz.getDeclaredFields(); |
|
|
|
|
|
|
|
declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Throwable ex) { |
|
|
|
|
|
|
|
throw new IllegalStateException("Failed to introspect Class [" + clazz + |
|
|
|
|
|
|
|
"] from ClassLoader [" + clazz.getClassLoader() + "]", ex); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -720,6 +742,7 @@ public abstract class ReflectionUtils { |
|
|
|
* Given the source object and the destination, which must be the same class
|
|
|
|
* Given the source object and the destination, which must be the same class
|
|
|
|
* or a subclass, copy all fields, including inherited fields. Designed to |
|
|
|
* or a subclass, copy all fields, including inherited fields. Designed to |
|
|
|
* work on objects with public no-arg constructors. |
|
|
|
* work on objects with public no-arg constructors. |
|
|
|
|
|
|
|
* @throws IllegalStateException if introspection fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void shallowCopyFieldState(final Object src, final Object dest) { |
|
|
|
public static void shallowCopyFieldState(final Object src, final Object dest) { |
|
|
|
if (src == null) { |
|
|
|
if (src == null) { |
|
|
|
|