Saturday 7 February 2015

What is Type Erasure in Java Generics

Introduction:
Generics is one the most important features introduced in JDK 1.5.this feature is provided to perform compile-time checking and removing risk of ClassCastException that occures at runtime generally working with collections.

The whole collection framework re-written to use generics for type-safety. Lets discuss, how we can avoid type-safety in JDK 1.5 through examples.

JDK 1.4 coding style:
List collection = new ArrayList();
colection.add("This is a String object");
collection.add(new Integer(10));
collection.add(new UserdefinedObject());

for(int index = 0; index < collection.size(); index++) {
     Integer int = (Integer) collection.get(index);
}
Here, there is no type-check validation performed at compilation time. Hence, any kind of objected can be able to added the list. But while iterating at run-time there is no guarantee that all the elements are of type Integer. So there are more chances of getting ClasscastException.

To overcome this limitation, generics are introduced in JDK 5.

JDK 1.5 coding style:
List<Integer> collection = new ArrayList<Integer>();
collection.add(new Integer(10));
collection.add(new UserdefinedObject()); // Gives compilation error

for(Integer int : collection) {
    // No explicit casting required, since the collcetion object have only Integer objects.
}

What is Type Erasure in Generics:
To discuss this, lets take an example. We have a requirement to create two similar methods(overloading), one to accept list of Employee objects and another to accept list of Assests objects to perform required business logic.

So, our code looks like as follows:
public Double calculateCost(List<Employee> empList) {
     // business logic 
}
public Double calculateCost(List<Asset> assetList) (
     // business logic 
}
The above gives compilation error, saying "Method has the same easure as another method in type".

The reason for above compilation error is due to Java generics uses type erasure. It means that, Java generics is implemented on the compilation level. The byte code generated from compiler does not contain type information of generic type for the run-time execution.

After compilation, both list of employee and list of assest become List.
If we observe the code by using Java Decompiler, the code looks like below:
public Double calculateCost(List empList) { }
public Double calculateCost(List assetList) { }
Hence, while runtime both methods appears same signature. So JVM gets ambiguity to call which method to perform required operation.

In the case of above situations, we can use Wildcard characters in the methods signature as follows:
public Double calculateCost(List<?> list) { }

Note:
During the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded or Object if the type parameter is unbounded.

Reference : http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
.