Java type declaration

Well, there have been many questions on this site regarding raw types and generics in Java. Even questions as to why the warning appears in the next line of code:

List<String> list = new ArrayList();

      

And answered many times because ArrayList () is of raw type, so the compiler raises a warning as it is list

no longer "type safe" and the ability to write this line of code is purely for backward compatibility.

What I don’t understand and didn’t find any questions about it, why? Since the compiler compiles Java code by "looking" only at static references, what is the difference in compile time for writing new ArrayList();

instead new ArrayList<>();

.

For example, writing this code:

List<String> list = new ArrayList(); // 1
list.add("A string"); // 2
list.add(new Object()); // 3

      

prints a compilation warning on line 1, not a compilation problem on line 2, but a compilation error on line 3 - type safety.

Therefore - adding a general reference to the first line ( new ArrayList<>();

) only removes the compiler warning.

I realize it is a bad habit to use raw types, but my question really is what is the difference (other than a compile-time warning) when writing the right side as a raw type.

Thank!

+3


source to share


2 answers


The compiler doesn't care which engine created the object your variable refers to list

. In fact, it can also link to null

. Or it could be a method call. Example:

void yourMethod() {
    List<String> list = createStringList();
    ...
}

List<String> createStringList() {
    return new ArrayList(); // raw type here
}

      

Given a valid typed variable (which has not been declared with a raw type), all uses of that variable are checked against the generic type.



It's another matter 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 just fine, but the warning should warn you because something might break later!

+2


source


Suppose you have another class where the constructor parameters depend on the type parameter:

class Foo<T> {
    Foo(T obj) { }
}

      

The compiler then checks the type of the parameter when it is created using the type parameter or the diamond operator:

 Foo<String> bar = new Foo<>(42); // doesn't compile

      



But raw types disable checking for generic features:

 Foo<String> bar = new Foo(42); // does compile but causes heap pollution

      

therefore it is necessary to warn.

+1


source







All Articles