Why does the compiler allow references to generic types that are not parameterized? [duplicate]

StackOverflow https://stackoverflow.com/questions/17290718

  •  01-06-2022
  •  | 
  •  

Question

Why does the compiler only give a warning ("ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized") and compile the code? Why doesn't it give an error as at run time compiler will not be able to type cast our data into the specified parameter type?

Was it helpful?

Solution 2

Consider an example when arraylists are not parameterized

 ArrayList listOfObjects = new ArrayList();

 listOfObjects.add("someStringValue");
 listOfObjects.add(new Integer(10));
 listOfObjects.add(new Dog());

Everything is valid here so you can add anything in the listOfObjects.

But if you parameterize it,

 ArrayList<String> listOfStrings = new ArrayList<String>();
 listOfStrings.add("someStringValue");
 listOfStrings.add(new Dog()); // Boom, compiler error, can't add dogs into list of strings

Compilation is successful because the generic code needs to be compatible with the legacy code in which generics are not used.

Also there is no type safety at runtime,

OTHER TIPS

References to generic types without arguments are called raw types.

The only reason why the compiler allows their use is backwards compatibility: each generation of Java compilers tries to be as backwards compatible to older code as possible. And since generics where introduced in Java 5, a lot of older code simply didn't use them.

A quote from the JLS (as linked above):

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. It is possible that future versions of the Java programming language will disallow the use of raw types.

Since Sun didn't want to introduce a parallel universe to ArrayList and related classes, it decided to add generic type information to collections (and many other places) and define the JLS in a way that allows old, non-generic code still to compile (with a warning, however).

In well-written, new code that doesn't interface with old and/or broken libraries raw types should never be necessary.

Generics were introduced in Java to provide the uniformity to the collection.

i.e. if you pass a collection to the method without generics then, the method will not know what to expect when an element is retrieved from the collection.

e.g. if you pass a collection consisting of all Strings without generics then, the method may insert an Object into it which is not correct.

Generics are only available till compilation. After compilation, "type erasure" takes place and all the generics are vanished by the compiler.

Type erasure is explained in this link.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top