了解 Guava 的 TypeToken.isAssignableFrom 方法



我正在使用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

为什么对CCD_ 4的第二次调用返回CCD_?,考虑到下面的代码是编译的,所以我可以从List分配List<String>(带警告(?:

List l = null;
List<String> l2 = null;
l = l2; 
l2 = l; //Type Safety Warning 

我的直觉是,Guava在回答这些类型的实例是否可以在没有警告的情况下赋值(?(。如果这是正确的,我该如何检查可分配性,因为编译器允许我将一个对象分配给另一个对象(有或没有警告(,就像第二个代码片段中显示的那样?。

正如您所说,我们知道编译器将允许从原始类型分配泛型类型,但这并不意味着可分配性。编译器正在执行隐式的未检查强制转换(因此发出警告(。

由于您确实想检查相应原始类型的可分配性,所以可以先使用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);
}

请注意,此解决方案不考虑数组类型。

相关内容

  • 没有找到相关文章

最新更新