Reputation: 1505
Well, there were many question on this site regarding raw types and generics in Java. Even questions regarding why does the next line of code comes up with a warning:
List<String> list = new ArrayList();
And answered many times, since ArrayList() is of raw type, therefore the compiler raises a warning since now list
is not "type safe", and the option to write this line of code is solely for backward compatibility.
What I don't understand, and didn't find questions about it, is why? Since the compiler compiles the Java code by "looking" only on the static references, how come there is a difference in compilation time for writing new ArrayList();
instead of new ArrayList<>();
.
For example, writing this code:
List<String> list = new ArrayList(); // 1
list.add("A string"); // 2
list.add(new Object()); // 3
results in a compilation warning in line 1, no compilation problem in line 2, but a compilation error in line 3 - of type safety.
Therefore - adding a generic reference to the first line (new ArrayList<>();
), results only in the removal of the compiler warning.
I understand it's a bad habit to use raw types, but my question is really what is the difference (except for the compilation warning) in writing the right hand side as a raw type.
Thanks!
Upvotes: 3
Views: 985
Reputation: 122429
Suppose you have another class where the constructor parameters depend on the type parameter:
class Foo<T> {
Foo(T obj) { }
}
Then the compiler checks the parameter type when you create it with a type parameter or diamond operator:
Foo<String> bar = new Foo<>(42); // doesn't compile
But raw types turns off generics checking:
Foo<String> bar = new Foo(42); // does compile but causes heap pollution
so a warning is necessary.
Upvotes: 2
Reputation: 20608
The compiler does not care what mechanism created the object that your variable list
refers to. In fact, it could also refer to null
. Or it could be a call to a method. Example:
void yourMethod() {
List<String> list = createStringList();
...
}
List<String> createStringList() {
return new ArrayList(); // raw type here
}
When having a proper typed variable (that was not declared with a raw type) all usages of this variable are checked against the generic type.
Another thing would be if your variable itself is declared with a raw type: Example:
List list = new ArrayList();
list.add("A string");
list.add(new Object());
This compiles fine, but the warning should alert you because things may break later!
Upvotes: 2