0

In Java, generic types are erased at compilation and instead Object is substituted for all generic parameters and an implicit cast is done. The reason for doing this is to maintain backward compatibility as explained here. Can anyone give a code example in pre-Java 1.5 which would cause issues at runtime if Java 1.5 did not erase types at compilation?

Community
  • 1
  • 1
qrius
  • 621
  • 2
  • 9
  • 22
  • 2
    https://docs.oracle.com/javase/tutorial/extra/generics/legacy.html – shmosel May 07 '17 at 23:44
  • 1
    This is actually kind of a difficult question to answer, because we're talking hypothetically. There are ways that reifiable types *could* have been implemented which are backwards-compatible (for example, maybe the raw type `List` is equivalent to `List` and unchecked conversion from a raw type to a parameterized type isn't allowed), but they chose not to for "theoretical" reasons. You might see the italicized note at the end of [JLS 4.7](https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.7). Any examples we make up won't necessarily cause unsolvable problems. – Radiodef May 07 '17 at 23:54
  • I think Mr Gomes' point is that type erasure gives us byte code compatibility with earlier releases. If the byte code for generic classes such as collections needed to include type information, any pre-Java 5 use of collections classes would need to be recompiled. – Dawood ibn Kareem May 08 '17 at 00:12
  • Type erasure does not happen at compile time, but at runtime. See [this answer](http://stackoverflow.com/a/15908823/5772882). – Ole V.V. May 08 '17 at 08:58

1 Answers1

1

I think you have misunderstood the purpose of Type Erasure, firstly - type erasure is not meant to avoid runtime exceptions (but it is meant to avoid any runtime performance penalty, more info coming...) and secondly - before Java SE 5 there was no "Generics" so there was no question of "type erasure".

Read here about purpose of type erasure:

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
  • Insert type casts if necessary to preserve type safety.
  • Generate bridge methods to preserve polymorphism in extended generic types.

Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.

So, among the main purpose of "type erasure" in generics is to avoid any runtime performance penalty, since all type parameter resolved and verified against type arguments at compile time so at runtime JVM need to waste any CPU cycles on that.

See below code, which shows that after compilation the types are resolved and the final bytecode which would be interpretted by JVM wouldn't have any type parameters left.

Before compilations:

import java.util.Arrays;
import java.util.List;

public class TypeErasureExample {
    public static void main(String[] args) {
        List<String> stringList = Arrays.asList(new String[]{"a", "b", "c"});
        List<?> numberList = Arrays.asList(new Integer[]{1, 2, 3});

        System.out.println(stringList);
        System.out.println(numberList);
    }
}

After compilation (decompiled o/p):

import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

public class TypeErasureExample
{
  public static void main(String[] paramArrayOfString)
  {
    List localList1 = Arrays.asList(new String[] { "a", "b", "c" }); // Notice "List<String>" is converted to "List", this is what type erasure does.
    List localList2 = Arrays.asList(new Integer[] { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3) }); // Notice "List<?>" is converted to "List", this is what type erasure does.

    System.out.println(localList1);
    System.out.println(localList2);
  }
}
hagrawal7777
  • 14,103
  • 5
  • 40
  • 70