This question already has an answer here:
- Java generic methods in generics classes 6 answers
- What is a raw type and why shouldn't we use it? 14 answers
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
...
From JLS 4.8 Raw Types
and
Which - if you read it carefully - implies that all types are erased, not just the type you left out.