为什么javac抱怨与类的类型参数无关的泛型?

参见英文答案 > Java generic methods in generics classes                                    6个
>            What is a raw type and why shouldn’t we use it?                                    15个
请按顺序阅读代码中的注释,问题详细信息.
为什么会发生这种差异?
如果可能,请引用JLS.

import java.util.*;

/**
 * Suppose I have a generic class
 * @param <T> with a type argument.
 */
class Generic<T> {
    // Apart from using T normally,
    T paramMethod() { return null; }
    // the class' interface also contains Generic Java Collections
    // which are not using T, but unrelated types.
    List<Integer> unrelatedMethod() { return null; }
}

@SuppressWarnings("unused")
public class Test {
    // If I use the class properly (with qualified type arguments)
    void properUsage() {
        Generic<String> g = new Generic<String>();

        // everything works fine.
        String s = g.paramMethod();
        List<Integer> pos = g.unrelatedMethod();

        // OK error: incompatible types: List<String> := List<Integer>
        List<String> thisShouldErrorCompile = g.unrelatedMethod();
    }

    // But when I use the raw type, *ALL* the generics support is gone, even the Collections'.
    void rawUsage() {
        // Using Generic<?> as the type turns fixes the warnings below.
        Generic g = new Generic();

        // OK error: incompatible types: String := Object
        String s = g.paramMethod();

        // WTF warning: unchecked conversion: List<Integer> := raw List
        List<Integer> pos = g.unrelatedMethod();

        // WTF warning: unchecked conversion: List<String> := raw List
        List<String> thisShouldErrorCompile = g.unrelatedMethod();
    }
}

边注

我最初在IntelliJ IDEA中发现了这个,但我想编译器与javac兼容,因为当我用以下代码编译上面的代码时,它给出了相同的错误/警告.

$javac -version
javac 1.7.0_05
$javac Test.java -Xlint:unchecked
...
$javac Test.java -Xlint:unchecked -source 1.5 -target 1.5
...

解决方法:

JLS 4.8 Raw Types

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged.

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

哪个 – 如果你仔细阅读 – 暗示所有类型都被删除,而不仅仅是你遗漏的类型.

上一篇:java泛型,未经检查的警告


下一篇:@suppresswarnings(unchecked)的作用