java - 理解 Guava 的 TypeToken.isAssignableFrom 方法

标签 java generics reflection types guava

我正在使用 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 会回答这些类型的实例是否可以在没有警告的情况下分配(?)。如果那是正确的,我如何检查编译器允许我将一个对象分配给另一个对象(有或没有警告)的意义上的可分配性,就像第二个代码片段中显示的那样? .

最佳答案

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

因为你真的想检查相应原始类型的可分配性,你可以只使用 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);
}

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

关于java - 理解 Guava 的 TypeToken.isAssignableFrom 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15054879/

相关文章:

java - 删除应用程序不同 session 之间的插件首选项

java - Spring JPA 自动扫描 jar 文件中的实体

java - Google Guice - 使用泛型作为注入(inject)字段的参数

reflection - 避免反射 - 我怎样才能最好地重构这段代码?

java - Java解析conf文件

函数类型的 Scala 类型推断

Java 泛型和数组类型

c# - 如何递归获取命名空间内的所有命名空间

actionscript-3 - 如何在 ActionScript 对象的祖先类上调用静态函数?

java - 写入文本文件时遇到问题