1

Type erasure only seems to occur when instantiating a generic type, but if you extend a generic type and provide a concrete type in place of T, the type is available at runtime. It seems to be the only time that the type isn't erased.

In the following example, String will be erased:

List<String> text = new ArrayList<>();

In the following example, as the implementation is still generic, any usage of it will erase whatever is in place of T.

public final class ArrayList<T> implements List<T> { ... }

But, the moment the implementation is no longer generic, where T has been replaced by a concrete type in the inheritance chain, it's discoverable via reflection.

public final class IntegerList implements List<Integer> { ... }

Why doesn't the type get erased when implemented via inheritance?

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • 1
    "*..but if you extend a generic type and provide a concrete type in place of T, the type is available at runtime. It seems to be the only time that the type isn't erased.*" not *only*, if `List` would be for instance class field, or method parameter or method return type we could also read it at runtime. Related: [Get generic type of java.util.List](https://stackoverflow.com/q/1942644) – Pshemo Feb 15 '23 at 17:39
  • 4
    "*Why doesn't the type get erased when implemented via inheritance?*" Simple answer: because reified types are good. The better question is why they didn't do it *more*, not less. The answer to that is: compatibility reasons. – Michael Feb 15 '23 at 17:43
  • 2
    Why? Because that information must be saved in the classfile, otherwise the compiler would need the source code if that class is used somewhere else (e.g. when compiling `List example = new IntegerList()` in a third class and only having no source for `IntegerList` [just from a JAR file?] ) or it would not be possible to check if the assignment is valid (at compile time) – user16320675 Feb 15 '23 at 17:56
  • Your `IntegerList` is not generic. Broadly speaking there is no type to erase. – Ole V.V. Feb 15 '23 at 18:11

1 Answers1

2

But, the moment the implementation is no longer generic ...

That's the answer. Type erasure occurs for generic types. The subclass IntegerList is not generic. Non-generic types are reifiable, which means that the types are available at runtime.

From the Java Language Specification, 4.7: Reifiable Types:

4.7 Reifiable Types

Because some type information is erased during compilation, not all types are available at run time. Types that are completely available at run time are known as reifiable types.

A type is reifiable if and only if one of the following holds:

• It refers to a non-generic class or interface type declaration.

...

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151