diff --git a/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java b/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java index 2c3a9e67de8..f3583d85d38 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java @@ -809,15 +809,29 @@ public abstract class ClassUtils { public static boolean isAssignable(Class lhsType, Class rhsType) { Assert.notNull(lhsType, "Left-hand side type must not be null"); Assert.notNull(rhsType, "Right-hand side type must not be null"); - return (lhsType.isAssignableFrom(rhsType) || - lhsType.equals(primitiveWrapperTypeMap.get(rhsType))); + if (lhsType.isAssignableFrom(rhsType)) { + return true; + } + if (lhsType.isPrimitive()) { + Class resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType); + if (resolvedPrimitive != null && lhsType.equals(resolvedPrimitive)) { + return true; + } + } + else { + Class resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType); + if (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)) { + return true; + } + } + return false; } /** * Determine if the given type is assignable from the given value, * assuming setting by reflection. Considers primitive wrapper classes * as assignable to the corresponding primitive types. - * @param type the target type + * @param type the target type * @param value the value that should be assigned to the type * @return if the type is assignable from the value */ diff --git a/org.springframework.core/src/test/java/org/springframework/util/ClassUtilsTests.java b/org.springframework.core/src/test/java/org/springframework/util/ClassUtilsTests.java index 60396f11a33..64a24084ba0 100644 --- a/org.springframework.core/src/test/java/org/springframework/util/ClassUtilsTests.java +++ b/org.springframework.core/src/test/java/org/springframework/util/ClassUtilsTests.java @@ -227,6 +227,21 @@ public class ClassUtilsTests extends TestCase { InnerClass.overloadedCalled); } + public void testIsAssignable() { + assertTrue(ClassUtils.isAssignable(Object.class, Object.class)); + assertTrue(ClassUtils.isAssignable(String.class, String.class)); + assertTrue(ClassUtils.isAssignable(Object.class, String.class)); + assertTrue(ClassUtils.isAssignable(Object.class, Integer.class)); + assertTrue(ClassUtils.isAssignable(Number.class, Integer.class)); + assertTrue(ClassUtils.isAssignable(Number.class, int.class)); + assertTrue(ClassUtils.isAssignable(Integer.class, int.class)); + assertTrue(ClassUtils.isAssignable(int.class, Integer.class)); + assertFalse(ClassUtils.isAssignable(String.class, Object.class)); + assertFalse(ClassUtils.isAssignable(Integer.class, Number.class)); + assertFalse(ClassUtils.isAssignable(Integer.class, double.class)); + assertFalse(ClassUtils.isAssignable(double.class, Integer.class)); + } + public void testClassPackageAsResourcePath() { String result = ClassUtils.classPackageAsResourcePath(Proxy.class); assertTrue(result.equals("java/lang/reflect"));