我正在使用Guava TypeToken
类来测试是否可以将任意类型的实例分配给其他类型的对象。
在以下代码段中,我正在测试声明为List
的类型是否可以从List<String>
分配,反之亦然:
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
为什么第二次调用isAssignableFrom
会返回false
?,因为下面的代码会编译,所以我可以从List<String>
分配List
(带警告)? :
List l = null;
List<String> l2 = null;
l = l2;
l2 = l; //Type Safety Warning
我的直觉是Guava正在回答这些类型的实例是否可以在没有警告的情况下分配(?)。如果这是正确的,我怎么能检查编译器意义上的 assignability ,允许我将一个对象分配给另一个(有或没有警告),就像它在第二个代码片段中所示?
答案 0 :(得分:3)
正如您所说,我们知道编译器将允许从原始类型分配泛型类型,但这并不意味着可分配性。编译器正在进行隐式未经检查的强制转换(因此警告)。
由于您确实想要检查相应原始类型的可分配性,因此您可以使用TypeToken.getRawType
然后使用Class.isAssignableFrom
。
编辑:正如您所指出的,此方法会将List<Integer>
和List<String>
分配给彼此。为了避免这种情况,我认为你需要一个更通用的解决方案:
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);
}
请注意,此解决方案不考虑数组类型。