简体   繁体   中英

Java raw type declaration

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!

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM