'Why is this type parameter preserved in the bytecode?

The type erasure page says that

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.

However, for the following class:

public class Foo<E extends CharSequence> {
    public E something;
}

javap -c Foo prints:

public class Foo<E extends java.lang.CharSequence> {
  public E something;
}

Why is the type parameter not replaced with the bound (CharSequence), but is preserved as E?



Solution 1:[1]

What you printed isn't bytecode. It is the method signature. It's put there so the compiler can enforce typesafety when compiling other classes that call it.

Solution 2:[2]

Type information is preserved on classes and methods, but not on actual fields. If you wrote

class Foo extends Bar<String> {
}

...you could extract Bar<String> at runtime, but if you had

new Bar<String>();

...you could not extract Bar<String> there.

Solution 3:[3]

The type parameter is preserved because it must be known for sub-classing. Definitions

public class Foo<E extends CharSequence> 

and

public class Foo<CharSequence> 

are NOT equal, since latter would not allow sub-class to be declared as, say:

public class MyStringFoo extends Foo<String> { }

whereas former does.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user207421
Solution 2
Solution 3 StaxMan