Bozho
Bozho

Reputation: 597224

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?

Upvotes: 8

Views: 822

Answers (4)

imraklr
imraklr

Reputation: 317

I agree with @user207421 answer. One can differentiate between raw types and complete generic type by trying out the following code:

public class App {
    public static void main(String args[]) {
        Foo raw = new Foo(Something);
    }
}

When you check the bytecode for this class, you will find that E is missing. So this is a raw type. These raw types are not bounded and may even require casting due to which Exceptions might be thrown. That is why Generics are used; to ensure type safety. It is a complete source code mechanism.

Upvotes: 0

Louis Wasserman
Louis Wasserman

Reputation: 198211

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.

Upvotes: 2

StaxMan
StaxMan

Reputation: 116572

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.

Upvotes: -1

user207421
user207421

Reputation: 310980

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.

Upvotes: 8

Related Questions