Java 了解番石榴';s TypeToken.isAssignableFrom方法

Java 了解番石榴';s TypeToken.isAssignableFrom方法,java,generics,reflection,types,guava,Java,Generics,Reflection,Types,Guava,我使用GuavaTypeToken类来测试是否可以将任意类型的实例分配给其他类型的对象 在下面的代码片段中,我正在测试声明为List的类型是否可从List分配,反之亦然: TypeToken rawListType = new TypeToken<List>(){}; TypeToken parameterizedListType = new TypeToken<List<String>>(){}; System.out.println(rawListType

我使用Guava
TypeToken
类来测试是否可以将任意类型的实例分配给其他类型的对象

在下面的代码片段中,我正在测试声明为
List
的类型是否可从
List
分配,反之亦然:

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

我的直觉是,如果这些类型的实例在没有警告的情况下是可分配的,那么Guava正在回答。如果这是正确的,我如何检查编译器允许我将一个对象分配给另一个对象(有警告或没有警告)意义上的可分配性,如第二个代码段所示?

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

由于您确实希望检查相应原始类型的可分配性,所以可以先使用,然后再使用

编辑:正如您所指出的,此方法将计算可相互分配的
List
List
。为了避免这种情况,我认为您需要一个更通用的解决方案:

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);
}
布尔checkRawAssignability(已分配的TypeToken,来自的TypeToken){
//如果from是原始类型,请改为比较原始类型
final Type fromType=from.getType();
if(类的fromType实例){
return assigned.getRawType().isAssignableFrom((类)fromType);
}
//否则使用正常的方法
已分配的返回。isAssignableFrom(from);
}

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

嗨@保罗。这并不完全是我要寻找的,若我检查原始类型的可分配性,那个么列表将是可从列表中分配的,诸如此类,这是不正确的。我正在寻找一种方法来验证可分配性,即使在编译器必须在courtains后面添加隐式强制转换的情况下也是如此。我认为您的解决方案是正确的,您知道TypeToken为什么不这样做吗?。至少他们应该在javadoc方法中记录这一点。@Sergio:IMHO TypeToken实现的是更重要的概念。编译器所做的是一种黑客行为(就像使用原始类型本身一样)。无论如何,它应该被记录下来,我建议这样做。
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);
}