Wildcard types, type erasure and runtime signature: what happens on <T extends A & B> where A and B inherit a common ancestor?

StackOverflow https://stackoverflow.com/questions/22426047

Pergunta

(edit: fixed after comments)

Let us take a class or interface A and an interface B where both inherit a common ancestor X (assuming X is not Object). Let us have a method whose signature is:

<T extends A & B> void foo(final T arg)

What is the signature of foo at runtime? Is that void foo(X) or void foo(Object), and the JVM casts to X at runtime?

Foi útil?

Solução

The erasure of a type parameter is always the erasure of its left-most bound, doesn't matter what other classes are up there in the inheritance hierarchy (JLS §4.6). So, the method is erased to:

void foo(final A)

Of course, as noted in comments, if A and B both are classes, that code will not compile. The type parameter bounds can not have multiple classes as bounds, but only a single class followed by any number of interfaces.

See JLS §4.4 for the syntax of type variable declaration:

TypeParameter:
    TypeVariable TypeBoundopt

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType AdditionalBoundListopt

AdditionalBoundList:
    AdditionalBound AdditionalBoundList
    AdditionalBound

AdditionalBound:
    & InterfaceType

Any AdditionalBound should always be an InterfaceType.

the JVM casts to X at runtime?

Yes the compiler will add appropriate cast so that the code works as intended.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top