mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Polishing (includes nullable declaration for internal type array)
This commit is contained in:
@@ -38,15 +38,16 @@ import org.springframework.lang.Contract;
|
||||
*/
|
||||
public abstract class TypeUtils {
|
||||
|
||||
private static final Type[] IMPLICIT_LOWER_BOUNDS = { null };
|
||||
private static final @Nullable Type[] IMPLICIT_LOWER_BOUNDS = { null };
|
||||
|
||||
private static final Type[] IMPLICIT_UPPER_BOUNDS = { Object.class };
|
||||
|
||||
|
||||
/**
|
||||
* Check if the right-hand side type may be assigned to the left-hand side
|
||||
* type following the Java generics rules.
|
||||
* @param lhsType the target type (left-hand side (LHS) type)
|
||||
* @param rhsType the value type (right-hand side (RHS) type) that should
|
||||
* @param lhsType the target type (left-hand side type)
|
||||
* @param rhsType the value type (right-hand side type) that should
|
||||
* be assigned to the target type
|
||||
* @return {@code true} if {@code rhsType} is assignable to {@code lhsType}
|
||||
* @see ClassUtils#isAssignable(Class, Class)
|
||||
@@ -55,37 +56,34 @@ public abstract class TypeUtils {
|
||||
Assert.notNull(lhsType, "Left-hand side type must not be null");
|
||||
Assert.notNull(rhsType, "Right-hand side type must not be null");
|
||||
|
||||
// all types are assignable to themselves and to class Object
|
||||
// All types are assignable to themselves and to class Object.
|
||||
if (lhsType.equals(rhsType) || Object.class == lhsType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lhsType instanceof Class<?> lhsClass) {
|
||||
// just comparing two classes
|
||||
// Just comparing two classes...
|
||||
if (rhsType instanceof Class<?> rhsClass) {
|
||||
return ClassUtils.isAssignable(lhsClass, rhsClass);
|
||||
}
|
||||
|
||||
if (rhsType instanceof ParameterizedType rhsParameterizedType) {
|
||||
Type rhsRaw = rhsParameterizedType.getRawType();
|
||||
|
||||
// a parameterized type is always assignable to its raw class type
|
||||
// A parameterized type is always assignable to its raw class type.
|
||||
if (rhsRaw instanceof Class<?> rhRawClass) {
|
||||
return ClassUtils.isAssignable(lhsClass, rhRawClass);
|
||||
}
|
||||
}
|
||||
else if (lhsClass.isArray() && rhsType instanceof GenericArrayType rhsGenericArrayType) {
|
||||
Type rhsComponent = rhsGenericArrayType.getGenericComponentType();
|
||||
|
||||
return isAssignable(lhsClass.componentType(), rhsComponent);
|
||||
}
|
||||
}
|
||||
|
||||
// parameterized types are only assignable to other parameterized types and class types
|
||||
// Parameterized types are only assignable to other parameterized types and class types.
|
||||
if (lhsType instanceof ParameterizedType lhsParameterizedType) {
|
||||
if (rhsType instanceof Class<?> rhsClass) {
|
||||
Type lhsRaw = lhsParameterizedType.getRawType();
|
||||
|
||||
if (lhsRaw instanceof Class<?> lhsClass) {
|
||||
return ClassUtils.isAssignable(lhsClass, rhsClass);
|
||||
}
|
||||
@@ -97,7 +95,6 @@ public abstract class TypeUtils {
|
||||
|
||||
if (lhsType instanceof GenericArrayType lhsGenericArrayType) {
|
||||
Type lhsComponent = lhsGenericArrayType.getGenericComponentType();
|
||||
|
||||
if (rhsType instanceof Class<?> rhsClass && rhsClass.isArray()) {
|
||||
return isAssignable(lhsComponent, rhsClass.componentType());
|
||||
}
|
||||
@@ -122,7 +119,6 @@ public abstract class TypeUtils {
|
||||
|
||||
Type[] lhsTypeArguments = lhsType.getActualTypeArguments();
|
||||
Type[] rhsTypeArguments = rhsType.getActualTypeArguments();
|
||||
|
||||
if (lhsTypeArguments.length != rhsTypeArguments.length) {
|
||||
return false;
|
||||
}
|
||||
@@ -130,7 +126,6 @@ public abstract class TypeUtils {
|
||||
for (int size = lhsTypeArguments.length, i = 0; i < size; ++i) {
|
||||
Type lhsArg = lhsTypeArguments[i];
|
||||
Type rhsArg = rhsTypeArguments[i];
|
||||
|
||||
if (!lhsArg.equals(rhsArg) &&
|
||||
!(lhsArg instanceof WildcardType wildcardType && isAssignable(wildcardType, rhsArg))) {
|
||||
return false;
|
||||
@@ -141,17 +136,14 @@ public abstract class TypeUtils {
|
||||
}
|
||||
|
||||
private static boolean isAssignable(WildcardType lhsType, Type rhsType) {
|
||||
Type[] lUpperBounds = getUpperBounds(lhsType);
|
||||
|
||||
Type[] lLowerBounds = getLowerBounds(lhsType);
|
||||
@Nullable Type[] lUpperBounds = getUpperBounds(lhsType);
|
||||
@Nullable Type[] lLowerBounds = getLowerBounds(lhsType);
|
||||
|
||||
if (rhsType instanceof WildcardType rhsWcType) {
|
||||
// both the upper and lower bounds of the right-hand side must be
|
||||
// completely enclosed in the upper and lower bounds of the left-
|
||||
// hand side.
|
||||
Type[] rUpperBounds = getUpperBounds(rhsWcType);
|
||||
|
||||
Type[] rLowerBounds = getLowerBounds(rhsWcType);
|
||||
// Both the upper and lower bounds of the right-hand side must be
|
||||
// completely enclosed in the upper and lower bounds of the left-hand side.
|
||||
@Nullable Type[] rUpperBounds = getUpperBounds(rhsWcType);
|
||||
@Nullable Type[] rLowerBounds = getLowerBounds(rhsWcType);
|
||||
|
||||
for (Type lBound : lUpperBounds) {
|
||||
for (Type rBound : rUpperBounds) {
|
||||
@@ -159,7 +151,6 @@ public abstract class TypeUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Type rBound : rLowerBounds) {
|
||||
if (!isAssignableBound(lBound, rBound)) {
|
||||
return false;
|
||||
@@ -173,7 +164,6 @@ public abstract class TypeUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Type rBound : rLowerBounds) {
|
||||
if (!isAssignableBound(rBound, lBound)) {
|
||||
return false;
|
||||
@@ -187,7 +177,6 @@ public abstract class TypeUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Type lBound : lLowerBounds) {
|
||||
if (!isAssignableBound(rhsType, lBound)) {
|
||||
return false;
|
||||
@@ -198,17 +187,15 @@ public abstract class TypeUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Type[] getLowerBounds(WildcardType wildcardType) {
|
||||
private static @Nullable Type[] getLowerBounds(WildcardType wildcardType) {
|
||||
Type[] lowerBounds = wildcardType.getLowerBounds();
|
||||
|
||||
// supply the implicit lower bound if none are specified
|
||||
// Supply the implicit lower bound if none are specified.
|
||||
return (lowerBounds.length == 0 ? IMPLICIT_LOWER_BOUNDS : lowerBounds);
|
||||
}
|
||||
|
||||
private static Type[] getUpperBounds(WildcardType wildcardType) {
|
||||
Type[] upperBounds = wildcardType.getUpperBounds();
|
||||
|
||||
// supply the implicit upper bound if none are specified
|
||||
// Supply the implicit upper bound if none are specified.
|
||||
return (upperBounds.length == 0 ? IMPLICIT_UPPER_BOUNDS : upperBounds);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user