具有独立于泛型类型的泛型方法的原始类型

jlo*_*rdo 7 java generics

这是chrert的问题的后续问题Generic classes with Collection getter of other types.如果您能为我的问题想出更好的标题,请随时编辑它:

下面的代码包含一个GenericClass<T>带有返回类型方法的泛型类T和另一个带有返回类型的方法Collection<String>,它显然独立于T.

现在,如果我实例化一个raw GenericClass(我永远不会这样做,所以这个问题更像是一个理论问题,以帮助理解正在发生的事情)然后在增强的for循环中调用该方法将不起作用,因为所有泛型类型信息似乎在使用原始类型时迷路.但是,当在一个赋值中调用相同的方法时,它可以工作(它警告类型不安全,但它编译).

在我看来,要么两者都行不通,要么两者都行不通.我不明白为什么一个有效,另一个没有.你有任何提示,或知道JLS的任何部分解释这种行为?

public class GenericClass<T>  {

    T doSomething() {
        return null;
    }

    Collection<String> getCollection() {
        return Collections.emptyList();
    }

    public static void main(String[] args) {
        GenericClass raw = new GenericClass();
        // This will not compile (Error message below)
        for (String str : raw.getCollection()) {
            // Type mismatch: cannot convert from element type Object to String
        }
        // This is only a warning:
        // Type safety: The expression of type Collection needs unchecked conversion to conform to Collection<String>
        Collection<String> coll = raw.getCollection();
        for (String string : coll) {
            // works just fine
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有一个相关的问题,连同这里接受的答案,解释了什么是非常好的:为什么这个通用的Java代码不会编译?

Lou*_*man 4

在第一种情况下,raw.getCollection()返回原始Collection. JLS 14.14.2指定了增强循环的类型检查for

如果 Type(在 FormalParameter 产生式中)是引用类型,则 TargetType 是 Type;否则,TargetType 是 I 的类型参数的捕获转换的上限,如果 I 是原始的,则为 Object。

(强调已添加)

在第二种情况下,您显式地将原始类型分配给泛型类型,这与正常情况一样会出现警告。