Friday, May 18, 2012

Type Erasure in Java

While reading some posts online I came across the following post -
List<integer> list = new ArrayList<integer>();
List&lt;integer&gt; list = new ArrayList&lt;integer&gt;();
list.add(1);
list.add(2);
List list1 = new ArrayList();
list1.add(&quot;Some String&quot;);
list.addAll(list1);


This code compiles and executes as well, this works because of Type Erasure concept in Java. I knew about Type Erasure but while reading more about it on internet I found some posts which were questioning on Type Erasure concept.
Following code makes more confusing about Type Erasure concept, if compiler removes all the information about type parameters and type arguments then how does following code works??

class A<T>{
}
class B extends A<String>{
 public B() {
  System.out.println(((ParameterizedType)getClass().
                      getGenericSuperclass()).getActualTypeArguments()[0]);
 }
}


public static void main(String args[]){
     new B();
}



Output of above code-
java.lang.String
Well some people might get confused by this but if you read carefully, Type Erasure docs says -
When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method.
Compiler does removes all the type parameter and type arguments information within the class but it maintains the information about the super class so the type arguments with it, and that is the reason why above code prints the java.lang.String.
Now lets see the first code snippet again-
List<Integer>list = new ArrayList<Integer>();
list.add(1);
list.add(2);
List list1 = new ArrayList();
list1.add("Some String");
list.addAll(list1);
This will not work with above code

String str = list.get(2);

Compiler will give error for above statement due to generics, but following code will work

Object str = list.get(2);

While iterating through list you can check data from the list by
for( int i = 0 ; i < list.size() ; i++ ){
     Object data = list.get(i);
     if(data instanceof Integer){
          System.out.println("Integer:"+data);
     }
     if(data instanceof String){
          System.out.println("String:"+data);
     }
}
Type Erasure concept allows Java code to work with the old Java libraries which were written before generics.

No comments:

Post a Comment

Ads Inside Post