Type Erasure in Java

Type Erasure is very important concept of Java Generics. I have seen many times in interview candidates rate themselves 8 out 10, but they have not heard about Type Erasure. Even Senior lever developers can not answer about the Type Erasure .

Type Erasure can be explained as the process of enforcing type constraint only at compile time and discarding the Type information at run-time.

When we compile the code Unbounded Type is replaced with Object. The compiler ensure the Type safety at compile time.

There are basically Two Types of Type Erasure, Type Erasure can occur at Class(or  variable) level and method level.

Class Level Type Erasure:

At the class level, type parameters on the class are discarded during code compilation and replaced with its first bound, or Object if the type is Unbounded.

public class Stack<T> {

     private T[] stackItem;

}

After compilation, the unbound Type T is replaced with  Object.

public class Stack{

    private Object[] stackItem;

}

 

In case of Bounded Type :

public CustomeStack <E extends Complarable<E>>{

private E[] items;

}

After compilation above code replace with first bounded type as given below

public CustomeStack {

private Comparable[] items;

}

Method Level Type Erasure:

For method level type erasure , the method’s type parameter is not stored but rather converted to its parent type Object if its unbounded or its first bound class when its bound.

 

Effects of Type Erasure and Bridge Methods:

When compiling a class or interface that extends a parameterized class or implements a parameterized interface, the compiler may need to create a synthetic method, called a bridge method, as part of the type erasure process. You normally don’t need to worry about bridge methods, but you might be puzzled if one appears in a stack trace.

 

public class Node {

    public Object data;

    public Node(Object data) { this.data = data; }

    public void setData(Object data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}

public class MyNode extends Node {

    public MyNode(Integer data) { super(data); }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}

After type erasure, the method signatures do not match. The Node method becomes setData(Object) and the MyNode method becomes setData(Integer). Therefore, the MyNode setData method does not override the Node setData method.

To solve this problem and preserve the polymorphism of generic types after type erasure, a Java compiler generates a bridge method to ensure that subtyping works as expected. For the MyNode class, the compiler generates the following bridge method for setData:

class MyNode extends Node {

    // Bridge method generated by the compiler
    public void setData(Object data) {
        setData((Integer) data);
    }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }

    // ...
}

As you can see, the bridge method, which has the same method signature as the Node class’s setData method after type erasure, delegates to the original setData method.

 

You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *