I am using the Guava TypeToken
class to test if instances of an arbitrary type can be assigned to objects of other type.
In the following code snippet, I am testing if types declared as List
are assignable from List<String>
, and viceversa:
TypeToken rawListType = new TypeToken<List>(){};
TypeToken parameterizedListType = new TypeToken<List<String>>(){};
System.out.println(rawListType.isAssignableFrom(parameterizedListType)); //true
System.out.println(parameterizedListType.isAssignableFrom(rawListType)); //false
Why the second call to isAssignableFrom
returns false
?, given that the code below does compile, so I can assign List<String>
from List
(with a warning) ?:
List l = null;
List<String> l2 = null;
l = l2;
l2 = l; //Type Safety Warning
My intuition is that Guava is answering if instances of these types are assignable without warnings (?). If that is correct, how could I check for assignability in the sense of the compiler allowing me to assign an object to another one (with or without warnings), like it is shown in the second code snippet ?.
As you said, we know the compiler will allow a generic type to be assigned from a raw type, but that doesn't mean assignability. The compiler is doing an implicit unchecked cast (hence the warning).
Since you really want to check assignability of the corresponding raw types, you could just use TypeToken.getRawType
and then use Class.isAssignableFrom
.
EDIT: As you pointed out, this methodology would count List<Integer>
and List<String>
assignable to and from each other. To avoid that I think you need a more generalized solution:
boolean checkRawAssignability(TypeToken<?> assigned, TypeToken<?> from) {
//if from is a raw type, compare raw types instead
final Type fromType = from.getType();
if (fromType instanceof Class<?>) {
return assigned.getRawType().isAssignableFrom((Class<?>)fromType);
}
//otherwise use normal methodology
return assigned.isAssignableFrom(from);
}
Note that this solution does not consider array types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With