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.

What’s Next?

java-generic-methods