Before Java 5, Java had no generics, and Classes like Box
and Interfaces like Collection
used the Object
type for all parameters & return types that were meant to be ‘Generic’.
To maintain backward compatibility, generic types in Java only exist in the source code and after type checking during compilation, is removed and does not exist in the bytecode. This is known as java-generics-type-erasure.
What!?
Resulting from this quirk, we have Raw Types in Java!
public static void main(String[] args) {
// Normal Initilisation
Box<String> a = new Box<String>();
// Normal Shorthand Initilisation
Box<String> b = new Box<>();
// Use of Raw Box Type
Box c = new Box();
// Putting a generic class with a parameterised type into a raw type
Box d = new Box<String>();
// Compile time error! Invalid assignment of raw type into a parameterised type
Box<String> = e new Box();
}
Although the code in the library for Box and other Classes and Interfaces now implement the Generics type system. Java, because of type erasure allows for the omitting of the generic type parameter! This will then then revert the behaviour of the Class/Interface to a ‘pre-generic’ state; treating everything as just Object
and performs no other type checking.
Java has been designed this way to allow for backwards compatibility between old Java code that do not have any generics and newer Java codebases. There is no reason to use Raw Types in modern Java, it is a feature strictly for backwards compatibility.