Understanding Type Erasure In Java

In this article, Parag Shah looks at Type Erasure in Java, a process where the compiler removes all information related to type parameters and type arguments within a class or method.


Generics were first introduced in Java 1.5 . Even though everyone understands what Generics are and how to use them, the concept of type erasure is a bit illusive. In this article I will explain type erasure in generics, using a simple example.

Angelika Langer has an excellent FAQ, where she explains generics, and type erasure. Here is how she defines type erasure: A process that maps a parameterized type (or method) to its unique byte code representation by eliding type parameters and arguments.

OK, let’s understand what that means. Listing-1 shows a simple class which uses generics with Java Lists. In this example we create a list of Strings and iterate through the list.

[java]
package net.adaptivelearningonline.examples.generics;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class GenericsErasure {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("Hello");
Iterator<String> iter = list.iterator();
while(iter.hasNext()) {
String s = iter.next();
System.out.println(s);
}
}
}
[/java]

Listing-1 : A simple class which uses Java generics

Now let’s do a little experiment to understand what type erasure means.

* Compile the above class
* Decompile GenericsErasure.class using JAD

The source generated from the decompilation is shown in Listing-2.

[java]
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: GenericsErasure.java

package net.adaptivelearningonline.examples.generics;

import java.io.PrintStream;
import java.util.*;

public class GenericsErasure
{

public GenericsErasure()
{
}

public static void main(String args[])
{
List list = new ArrayList();
list.add("Hello");
String s;
for(Iterator iter = list.iterator(); iter.hasNext(); System.out.println(s))
s = (String)iter.next();

}
}
[/java]

Listing-2 : Source of class (from Listing-1) decompiled by JAD

As you can see, the decompiled code has absolutely no trace of any generics related information when the List is declared. This is because of type erasure. Now let’s revisit Angelika’s definition of type erasure:

A process that maps a parameterized type (or method) to its unique byte code representation by eliding type parameters and arguments.

When the Java compiler compiles client code which uses a library that has been generified, the client code is compiled in such a way that all generics information (‘type parameters and arguments’ which is the in List) is erased from the bytecode. This also explains the fact that generics information in client code is meant purely for the compiler to do type checking. Once the compiler has done it’s job, this information is discarded.

If you are wondering why Java erases generics type information from compiled code – it is to maintain backwards compatibility. Let’s assume you wrote some code a few years back which used Java Lists, before generics was introduced in the language. Obviously your code did not use generics.

So back then you must have declared your List like this:

[java]
List list = new ArrayList();
[/java]

Listing-3

and not like this:

[java]
List<String> list = new ArrayList<String>();
[/java]

Listing-4

Now, when engineers at Sun decided to introduce generics, they did not want to break code which people had already written. Their solution to this problem was to ensure that client code which uses generics in the classes they invoke, never carries any information about generics in the compiled classfile. Because compiled client code never carries information about generics anyways, people were not forced to change their old code shown in Listing-3 to code shown in Listing-4. Thus library developers were free to add generics to their code without worrying about breaking old code which used their library.

To summarize, type erasure is the process by which type parameters and arguments are removed from the compiled bytecode, thus enabling library developers to port their libraries to use generics, without worrying about breaking old code.

Resources:

* A tutorial (pdf) on Java generics
* Oracle’s tutorial on type erasure
* Bruce Eckel’s excellent article on type erasure

Mujumdar Marg    214 Kasba Peth    Pune

Parag Shah

Parag has an M.S. in Computer Science from the University of North Carolina at Charlotte, and over 12 years of industry experience developing software and several years experience training developers in Java and software design principles. Please check out his one person company http://Adaptivesoftware.biz for more details. Parag's current obsession is to show that it is possible to do a DIY masters in Computer Science using open courseware and social learning principles. Check out his experiment at http://opencs.wikidot.com

6 thoughts on “Understanding Type Erasure In Java

  • July 23, 2010 at 6:24 pm
    Permalink

    Yes I too have come across several opinions on generics and type erasure in Java.

    In my experience I feel that the strength of type erasure is also it's weakness. It ensures backwards compatibility by not breaking old code which did not use generics, but this also allows us to write new code which bypasses having to specify type information.

    Regarding generics in particular, I feel that it does add a certain verbosity to the language which could have been simplified.

  • July 21, 2010 at 7:10 am
    Permalink

    Can you outline what kind of problems this can cause? (I hear a lot of people moan about Java's type erasure.)

  • July 20, 2010 at 1:11 pm
    Permalink

    Good article and good explanation of type erasure.I believe it can help people understand type erasure and the usefulness of generics!Good job! 🙂

Leave a Reply