Why does javac complain about generics unrelated to the class' type arguments? [duplicate]

冷暖自知 提交于 2019-11-26 02:02:45

问题


Please read the comments in the code in order, the question details are there.
Why is this difference happening?
Please quote the JLS if possible.

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();
    }
}

Side note

I originally found this in IntelliJ IDEA, but I guess that compiler is compatible with javac because when I compiled the above code with the following it gave the same errors/warnings.

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

回答1:


From 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.

and

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.

Which - if you read it carefully - implies that all types are erased, not just the type you left out.



来源:https://stackoverflow.com/questions/27314649/why-does-javac-complain-about-generics-unrelated-to-the-class-type-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!