Type Erasure

Last modified on August 1st, 2014 by Joe.

Type erasure is the technique using which the Java compiler translates generic / parameterized type to raw type in Java generics. Type erasure is applicable in the context of generics. Following example illustrates a simple usage of generics in Java.

package com.javapapers.java.generics;

import java.util.HashMap;
import java.util.Map;
 
public class TypeErasure {
  public static void main(String args[]) {
 
    Map genericsMap = new HashMap();
    Map noGenericsMap = new HashMap();

    genericsMap.put("1954", "FORTRAN");
    String language = genericsMap.get("1954");
    System.out.println("Language: "+language);
  }
}

In the above code, we instantiate a generic map using the parameterized type as String for generic type. It provides us the type safety and helps avoid the need for explicit casting.

Type erasure is a process to remove these types and map it to raw type in byte code and it is done during compilation by the Java compiler. You can take this as a near formal definition for type erasure. Java compiler replaces generic type information from source and adds casts as needed and delivers the byte code, generics related information are kept as meta-data in the bytecode for debugging, reflection purposes. With respect to general runtime execution, code will look like plain Java without generics.

Let us compile the above given Java source file and get a binary class file. Then de-compile that generated class file and inspect what type erasure has done. You may use any Java decompiler of your choice. For now the javap utility is sufficient for this simple inspection purpose. First compile the source and get a Java class file. Then run the command “javap -c TypeErasure“. Here TypeErasure is the name of the Java class.

C:\Users\Cycle\Desktop>javap -c TypeErasure
Compiled from "TypeErasure.java"
public class TypeErasure extends java.lang.Object{
public TypeErasure();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #2; //class java/util/HashMap
   3:   dup
   4:   invokespecial   #3; //Method java/util/HashMap."":()V
   7:   astore_1
   8:   new     #2; //class java/util/HashMap
   11:  dup
   12:  invokespecial   #3; //Method java/util/HashMap."":()V
   15:  astore_2
   16:  aload_1
   17:  ldc     #4; //String 1954
   19:  ldc     #5; //String FORTRAN
   21:  invokeinterface #6,  3; //InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
   26:  pop
   27:  aload_1
   28:  ldc     #4; //String 1954
   30:  invokeinterface #7,  2; //InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
   35:  checkcast       #8; //class java/lang/String
   38:  astore_3
   39:  getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;
   42:  new     #10; //class java/lang/StringBuilder
   45:  dup
   46:  invokespecial   #11; //Method java/lang/StringBuilder."":()V
   49:  ldc     #12; //String Language:
   51:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   54:  aload_3
   55:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   58:  invokevirtual   #14; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   61:  invokevirtual   #15; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   64:  return

}

Note two things in the above de-compiled code,

  1. “<String, String>” is missing on code line number 4. See there is no difference in bytecode for genericsMap and noGenericsMap object instantiation.
  2. (String)languageMap.get(“1954”) a type cast is added on code line number 35.

Type-Erasure

This is done by the java compiler while compiling java source code to byte code as part of the process java type erasure. Main reason behind having generics and type erasure is to give the programmer ability to write generic code and type safety. Generics is not forced, the generic type can be directly used as raw type instead of supplying parameterized type argument. But it is not a good coding practice.

Type Erasure Summary

At run-time the generic type is not available in general scenario, that’s what the type erasure does. There are scenarios where people accessing the generic type using reflection or non-java API.

T instantiateElementType(List arg)
{
  return new T(); //causes a compilation error
}

Basics of Generics will help us understand that ‘T’ is just a placeholder here and type erasure will remove it during compilation. Generics and type erasure is good for a programmer. Advantage we get in using generics is type safety and clarity in code, so embrace it.

Comments on "Type Erasure"

  1. Muthukumar says:

    Good analysis….

  2. Pinoy Java Blog says:

    Hi,

    Interesting blog you got. This is like a haven for java devs! I blog about Java too but with all other technologies. Anyway, nice article about type erasures. I haven’t really heard of this yet and I need sometime to absorb all that I’ve read so far…

  3. hoque says:

    good catching………..

  4. gchatzip says:

    Nice catch there , hence i can not see with someone bother use type erasure as a programming technique instead of generics , only use i know of type erasure is to maintain binary compatibility with Java libraries and applications that were created before generics.

    Keep up the good work mate !

  5. Olo says:

    BTW2, you can very easily test this without resorting to JAD decompilation.

    Just make a class with a method that accepts of returns a generic type. That might even be a private method:

    import java.util.LinkedList;
    import java.util.List;

    public class GenericList {
    public static void main(String[] args) {
    List<Number> numberList = new LinkedList<Number>();
    numberList.add(Integer.valueOf(3));
    numberList.add(Long.valueOf(Long.MAX_VALUE));
    printList(numberList);
    }

    private static void printList(List<? extends Number> printedList) {
    System.out.println(“List: ” + printedList);
    }
    }

    Compile the class:

    javac GenericList.java

    Have a look at its contents:

    $ hexdump -C GenericList.class | less -in

    What you’ll see:

    ….
    000000b0 73 74 01 00 13 28 4c 6a 61 76 61 2f 75 74 69 6c |st…(Ljava/util|
    000000c0 2f 4c 69 73 74 3b 29 56 01 00 09 53 69 67 6e 61 |/List;)V…Signa|
    000000d0 74 75 72 65 01 00 28 28 4c 6a 61 76 61 2f 75 74 |ture..((Ljava/ut|
    000000e0 69 6c 2f 4c 69 73 74 3c 2b 4c 6a 61 76 61 2f 6c |il/List;)V.|
    ….

    Where did that java/lang/Number come from?

    If type erasure really did remove the generic information from compiled class file, there would be no mention of java.lang.Number as it exists only in generic declarations in the source! As you can see, the exact information about printList() method’s generic argument is placed in the “Signature” section of the class file.

    See also the official specification of Java class file format, section 4.4.4:

    http://java.sun.com/docs/books/vmspec/2nd-edition/ClassFileFormat-final-draft.pdf

    “4.4.4 Signatures
    Signatures are used to encode Java programming language type information that is
    not part of the Java virtual machine type system, such as generic type and method
    declarations and parameterized types. See The Java Language Specification, Third
    Edition, for details about such types.
    This kind of type information is needed to support reflection and
    debugging, and by the Java compiler.”

  6. j0hn says:

    Cool Site :-)

  7. Panneer says:

    It’s good to read in this site..
    Im going to prefer this to my friends!!

  8. sumanta says:

    nice explanation for type erasure, superb answer

  9. Bhabani Padhy says:

    It really helps me to understand about type erasure with the generics example.

    Really nice job :)

  10. Anonymous says:

    Can you explain Java Generics more in Detail in your next post?

  11. sathiya says:

    hi,

    This type erasure is nice concept,At first time i heard in this . I like this subject very much .Thanks for guide.

  12. Arun Kumar says:

    nice article

  13. Jaal says:

    Obviously this is the best place to learn what Type Erasure is.. Thanks a lot

  14. Arun Sundar S says:

    nice article,thanks:)

  15. […] bridge method is a synthetic method created during type erasure. Let us see see about bridge method is a detailed separate […]

  16. kapil says:

    My question is :
    BottomLine Do we have to use type erasure or not…because why one should decompile the class again & then use it…
    an u give me a real life example where one should use it…

  17. Anuj says:

    I like your post.
    Great helps and this article is good.

  18. Joe says:

    Kapil,

    Type erasure is done by the Java compiler. We as a programmer got to use generics and that it. We are not doing anything explicitly for Type erasure. It is done during compilation process. You got to read the tutorial line by line. :-)

  19. Joe says:

    Welcome Arun.

  20. Joe says:

    welcome Sathiya.

  21. Joe says:

    Thanks John.

  22. Joe says:

    Thanks Pinoy, you too have got a nice blog.

  23. Joe says:

    Thanks Hoque.

  24. Joe says:

    The point that, “the complete generic information is not erased” is right and I agree with that. Information related to generics are retained as meta information in class file. Thanks Olo, I have updated the tutorial above.

    But erasure happens during runtime is wrong, it happens during compile time.

  25. Joe says:

    Thats fine. Yes thats right, type erasure does not completely erase the generics information and it retains type information as meta-data in binary class.

  26. Bob says:

    This is one of the reasons why Java has so much hate attached to it. Unfortunately it could of been a good language but due to the little things like type erasure, it has become a target of hate.

  27. […] the compiler translates the generics type information to raw types and this process is called type erasure. That is the type parameter like <T> are replaced by the left most bound type and in case if […]

Comments are closed for "Type Erasure".