为什么Guava的TypeToken <t> .getRawType()返回Class <! - ? super T - >而不是Class <t> </t> </t>

时间:2012-06-29 12:06:54

标签: java generics guava

从Effective Java Second Edition,第28项:“不要使用通配符类型作为返回类型。不是为用户提供额外的灵活性,而是强制他们在客户端代码中使用通配符类型。”

public final Class<? super T> getRawType()

我刚刚开始掌握通用通配符,以了解我在编写的一段代码中最后一次未经检查的强制转换警告,我不明白为什么getRawType()会返回一个通配符类型。

class Base<T>{}
class Child<T> extends Base<T>{}

public <C> void test (TypeToken<? extends Base<C>> token) {
    Class<? extends Base<C>> rawType = (Class<? extends Base<C>>) token.getRawType();
}

我必须在返回

时强制转换token.getRawType()
Class<? super ? extends Base<C>>

2 个答案:

答案 0 :(得分:8)

如果您有TypeToken<ArrayList<String>>并希望得到Class<ArrayList> 是原始类型),该怎么办?如果它返回Class<T>,那么它将返回Class<ArrayList<String>>,而不是Class<ArrayList>

答案 1 :(得分:0)

如果“token”的泛型类型是Type类(即,如果是

中的S)
TypeToken<S>

是一个java.lang.reflect.Type类),然后TypeToken.getRawType()将返回与S关联的原始类型。它应该是一个Class对象,S的父类。

请参阅TypeToken的源代码。

在某些情况下(比如有多个边界),实施的策略不起作用,原始类型为Ok:原始类型为Object.class

例如参见MoreTypes

public static Class<?> getRawType(Type type) {
...
} else if (type instanceof TypeVariable) {
  // we could use the variable's bounds, but that'll won't work if there are multiple.
  // having a raw type that's more general than necessary is okay  
  return Object.class;

} else {
...
}