Mainly for internal use within the framework. * * @author Juergen Hoeller * @author Keith Donald @@ -243,7 +244,7 @@ public abstract class ClassUtils { * style (e.g. "java.lang.Thread.State" instead of "java.lang.Thread$State"). * @param name the name of the Class * @param classLoader the class loader to use - * (may be {@code null}, which indicates the default class loader) + * (can be {@code null}, which indicates the default class loader) * @return a class instance for the supplied name * @throws ClassNotFoundException if the class was not found * @throws LinkageError if the class file could not be loaded @@ -314,7 +315,7 @@ public abstract class ClassUtils { * the exceptions thrown in case of class loading failure. * @param className the name of the Class * @param classLoader the class loader to use - * (may be {@code null}, which indicates the default class loader) + * (can be {@code null}, which indicates the default class loader) * @return a class instance for the supplied name * @throws IllegalArgumentException if the class name was not resolvable * (that is, the class could not be found or the class file could not be loaded) @@ -348,7 +349,7 @@ public abstract class ClassUtils { * one of its dependencies is not present or cannot be loaded. * @param className the name of the class to check * @param classLoader the class loader to use - * (may be {@code null} which indicates the default class loader) + * (can be {@code null} which indicates the default class loader) * @return whether the specified class is present (including all of its * superclasses and interfaces) * @throws IllegalStateException if the corresponding class is resolvable but @@ -375,7 +376,7 @@ public abstract class ClassUtils { * Check whether the given class is visible in the given ClassLoader. * @param clazz the class to check (typically an interface) * @param classLoader the ClassLoader to check against - * (may be {@code null} in which case this method will always return {@code true}) + * (can be {@code null} in which case this method will always return {@code true}) */ public static boolean isVisible(Class> clazz, @Nullable ClassLoader classLoader) { if (classLoader == null) { @@ -399,7 +400,7 @@ public abstract class ClassUtils { * i.e. whether it is loaded by the given ClassLoader or a parent of it. * @param clazz the class to analyze * @param classLoader the ClassLoader to potentially cache metadata in - * (may be {@code null} which indicates the system class loader) + * (can be {@code null} which indicates the system class loader) */ public static boolean isCacheSafe(Class> clazz, @Nullable ClassLoader classLoader) { Assert.notNull(clazz, "Class must not be null"); @@ -539,9 +540,10 @@ public abstract class ClassUtils { * Check if the right-hand side type may be assigned to the left-hand side * type, assuming setting by reflection. Considers primitive wrapper * classes as assignable to the corresponding primitive types. - * @param lhsType the target type - * @param rhsType the value type that should be assigned to the target type - * @return if the target type is assignable from the value type + * @param lhsType the target type (left-hand side (LHS) type) + * @param rhsType the value type (right-hand side (RHS) type) that should + * be assigned to the target type + * @return {@code true} if {@code rhsType} is assignable to {@code lhsType} * @see TypeUtils#isAssignable(java.lang.reflect.Type, java.lang.reflect.Type) */ public static boolean isAssignable(Class> lhsType, Class> rhsType) { @@ -662,7 +664,7 @@ public abstract class ClassUtils { * in the given collection. *
Basically like {@code AbstractCollection.toString()}, but stripping * the "class "/"interface " prefix before every class name. - * @param classes a Collection of Class objects (may be {@code null}) + * @param classes a Collection of Class objects (can be {@code null}) * @return a String of form "[com.foo.Bar, com.foo.Baz]" * @see java.util.AbstractCollection#toString() */ @@ -717,7 +719,7 @@ public abstract class ClassUtils { *
If the class itself is an interface, it gets returned as sole interface. * @param clazz the class to analyze for interfaces * @param classLoader the ClassLoader that the interfaces need to be visible in - * (may be {@code null} when accepting all declared interfaces) + * (can be {@code null} when accepting all declared interfaces) * @return all interfaces that the given object implements as an array */ public static Class>[] getAllInterfacesForClass(Class> clazz, @Nullable ClassLoader classLoader) { @@ -752,7 +754,7 @@ public abstract class ClassUtils { *
If the class itself is an interface, it gets returned as sole interface.
* @param clazz the class to analyze for interfaces
* @param classLoader the ClassLoader that the interfaces need to be visible in
- * (may be {@code null} when accepting all declared interfaces)
+ * (can be {@code null} when accepting all declared interfaces)
* @return all interfaces that the given object implements as a Set
*/
public static Set NOTE: In contrast to {@link org.springframework.aop.support.AopUtils#getMostSpecificMethod},
* this method does not resolve bridge methods automatically.
* Call {@link org.springframework.core.BridgeMethodResolver#findBridgedMethod}
- * if bridge method resolution is desirable (e.g. for obtaining metadata from
- * the original method definition).
- * NOTE: Since Spring 3.1.1, if Java security settings disallow reflective
- * access (e.g. calls to {@code Class#getDeclaredMethods} etc, this implementation
- * will fall back to returning the originally provided method.
+ * if bridge method resolution is desirable — for example, to obtain
+ * metadata from the original method definition.
+ * NOTE: If Java security settings disallow reflective access —
+ * for example, calls to {@code Class#getDeclaredMethods}, etc. — this
+ * implementation will fall back to returning the originally provided method.
* @param method the method to be invoked, which may come from an interface
* @param targetClass the target class for the current invocation
- * (may be {@code null} or may not even implement the method)
+ * (can be {@code null} or may not even implement the method)
* @return the specific target method, or the original method if the
* {@code targetClass} does not implement it
* @see #getInterfaceMethodIfPossible(Method, Class)
*/
public static Method getMostSpecificMethod(Method method, @Nullable Class> targetClass) {
- if (targetClass != null && targetClass != method.getDeclaringClass() && isOverridable(method, targetClass)) {
+ if (targetClass != null && targetClass != method.getDeclaringClass() &&
+ (isOverridable(method, targetClass) || !method.getDeclaringClass().isAssignableFrom(targetClass))) {
try {
if (Modifier.isPublic(method.getModifiers())) {
try {