/** * <p>Checks if the subject type may be implicitly cast to the target type * following the Java generics rules. If both types are {@link Class} * objects, the method returns the result of * {@link ClassUtils#isAssignable(Class, Class)}.</p> * * @param type the subject type to be assigned to the target type * @param toType the target type * @return {@code true} if {@code type} is assignable to {@code toType}. */ public static boolean isAssignable(final Type type, final Type toType) { return isAssignable(type, toType, null); }
/** * <p>Checks if the subject type may be implicitly cast to the target type * following the Java generics rules.</p> * * @param type the subject type to be assigned to the target type * @param toType the target type * @param typeVarAssigns optional map of type variable assignments * @return {@code true} if {@code type} is assignable to {@code toType}. */ private static boolean isAssignable(final Type type, final Type toType, final Map<TypeVariable<?>, Type> typeVarAssigns) { if (toType == null || toType instanceof Class<?>) { return isAssignable(type, (Class<?>) toType); } if (toType instanceof ParameterizedType) { return isAssignable(type, (ParameterizedType) toType, typeVarAssigns); } if (toType instanceof GenericArrayType) { return isAssignable(type, (GenericArrayType) toType, typeVarAssigns); } if (toType instanceof WildcardType) { return isAssignable(type, (WildcardType) toType, typeVarAssigns); } if (toType instanceof TypeVariable<?>) { return isAssignable(type, (TypeVariable<?>) toType, typeVarAssigns); } throw new IllegalStateException("found an unhandled type: " + toType); }
/** * <p>Checks if the given value can be assigned to the target type * following the Java generics rules.</p> * * @param value the value to be checked * @param type the target type * @return {@code true} if {@code value} is an instance of {@code type}. */ public static boolean isInstance(final Object value, final Type type) { if (type == null) { return false; } return value == null ? !(type instanceof Class<?>) || !((Class<?>) type).isPrimitive() : isAssignable(value.getClass(), type, null); }
if (isAssignable(midClass, superClass) && isAssignable(genericInterface, (Type) midClass)) { genericInterface = midType;
if (type1 != type2 && isAssignable(type2, type1, null)) { subtypeFound = true; break;
&& isAssignable(cls.getComponentType(), toComponentType, typeVarAssigns); return isAssignable(((GenericArrayType) type).getGenericComponentType(), toComponentType, typeVarAssigns); if (isAssignable(bound, toGenericArrayType)) { return true; if (isAssignable(bound, toGenericArrayType)) { return true;
if (isAssignable(bound, toTypeVariable, typeVarAssigns)) { return true;
/** * <p>Determines whether or not specified types satisfy the bounds of their * mapped type variables. When a type parameter extends another (such as * {@code <T, S extends T>}), uses another as a type parameter (such as * {@code <T, S extends Comparable>>}), or otherwise depends on * another type variable to be specified, the dependencies must be included * in {@code typeVarAssigns}.</p> * * @param typeVarAssigns specifies the potential types to be assigned to the * type variables, not {@code null}. * @return whether or not the types can be assigned to their respective type * variables. */ public static boolean typesSatisfyVariables(final Map<TypeVariable<?>, Type> typeVarAssigns) { Validate.notNull(typeVarAssigns, "typeVarAssigns is null"); // all types must be assignable to all the bounds of their mapped // type variable. for (final Map.Entry<TypeVariable<?>, Type> entry : typeVarAssigns.entrySet()) { final TypeVariable<?> typeVar = entry.getKey(); final Type type = entry.getValue(); for (final Type bound : getImplicitBounds(typeVar)) { if (!isAssignable(type, substituteTypeVariables(bound, typeVarAssigns), typeVarAssigns)) { return false; } } } return true; }
/** * Create a parameterized type instance. * * @param owner the owning type * @param raw the raw class to create a parameterized type instance for * @param typeArguments the types used for parameterization * * @return {@link ParameterizedType} * @since 3.2 */ public static final ParameterizedType parameterizeWithOwner(final Type owner, final Class<?> raw, final Type... typeArguments) { Validate.notNull(raw, "raw class is null"); final Type useOwner; if (raw.getEnclosingClass() == null) { Validate.isTrue(owner == null, "no owner allowed for top-level %s", raw); useOwner = null; } else if (owner == null) { useOwner = raw.getEnclosingClass(); } else { Validate.isTrue(isAssignable(owner, raw.getEnclosingClass()), "%s is invalid owner type for parameterized %s", owner, raw); useOwner = owner; } Validate.noNullElements(typeArguments, "null type argument at index %s"); Validate.isTrue(raw.getTypeParameters().length == typeArguments.length, "invalid number of type parameters specified: expected %d, got %d", raw.getTypeParameters().length, typeArguments.length); return new ParameterizedTypeImpl(raw, useOwner, typeArguments); }
return isAssignable(getRawType((ParameterizedType) type), toClass); if (isAssignable(bound, toClass)) { return true; return toClass.equals(Object.class) || toClass.isArray() && isAssignable(((GenericArrayType) type).getGenericComponentType(), toClass .getComponentType());
final Map<TypeVariable<?>, Type> subtypeVarAssigns) { if (!isAssignable(cls, toClass)) { return null;
if (!isAssignable(cls, toClass)) { return null;
for (final Type bound : getImplicitUpperBounds((WildcardType) type)) { if (isAssignable(bound, toClass)) { return getTypeArguments(bound, toClass, subtypeVarAssigns); for (final Type bound : getImplicitBounds((TypeVariable<?>) type)) { if (isAssignable(bound, toClass)) { return getTypeArguments(bound, toClass, subtypeVarAssigns);
public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) { final Type type1 = types[i1]; final Type type2 = types[i2]; final boolean isAssignable = TypeUtils.isAssignable(type2, type1); if (expected) { assertTrue("[" + i1 + ", " + i2 + "]: From " + String.valueOf(type2) + " to " + String.valueOf(type1), isAssignable); } else { assertFalse("[" + i1 + ", " + i2 + "]: From " + String.valueOf(type2) + " to " + String.valueOf(type1), isAssignable); } }
if (!isAssignable(bound, toBound, typeVarAssigns)) { return false; if (!isAssignable(toBound, bound, typeVarAssigns)) { return false; if (!isAssignable(type, substituteTypeVariables(toBound, typeVarAssigns), typeVarAssigns)) { return false; if (!isAssignable(substituteTypeVariables(toBound, typeVarAssigns), type, typeVarAssigns)) { return false;
&& !(toTypeArg instanceof WildcardType && isAssignable(fromTypeArg, toTypeArg, typeVarAssigns))) { return false;
if (!isAssignable(cls, superClass)) { return null;
@Test public void testLANG1190() throws Exception { final Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType(); final Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build(); assertTrue(TypeUtils.isAssignable(fromType, failingToType)); }
boolean isAssignable(Type src, Type target) { boolean assignable = TypeUtils.isAssignable(src, target); if (!assignable) { // void <--> java.lang.Void convert should be covered assignable = (src == void.class || src == Void.class) && (target == void.class || target == Void.class); } return assignable; }
final Type dat3Type = getClass().getField("dat3").getGenericType(); dis = dat; assertTrue(TypeUtils.isAssignable(datType, disType)); assertFalse(TypeUtils.isAssignable(daType, disType)); dis = uhder; assertTrue(TypeUtils.isAssignable(uhderType, disType)); dis = ding; assertFalse(String.format("type %s not assignable to %s!", dingType, disType), TypeUtils.isAssignable(dingType, disType)); dis = tester; assertTrue(TypeUtils.isAssignable(testerType, disType)); assertFalse(TypeUtils.isAssignable(tester2Type, disType)); assertFalse(TypeUtils.isAssignable(dat2Type, datType)); assertFalse(TypeUtils.isAssignable(datType, dat2Type)); assertFalse(TypeUtils.isAssignable(dat3Type, datType)); final char ch = 0; final boolean bo = false; double du = 0; du = ch; assertTrue(TypeUtils.isAssignable(char.class, double.class)); du = by; assertTrue(TypeUtils.isAssignable(byte.class, double.class)); du = sh;