Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type erasure, overriding and generics

Can someone explain to me why

@Override public void fooMethod(Class<?> c) 

doesn't override

public void fooMethod(Class c) 

and gives me the following errors instead:

 - Name clash: The method fooMethod(Class<?>)  of type SubClass has the same erasure as fooMethod(Class) of  type SuperClass but  does not override it   - The method fooMethod(Class<?>) of type  SubClass must override a superclass method 

?

Edit: "java -version" says Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284). As for the code snippet, it's already above, pretty much; the above extends the one below.

like image 521
Henrik Paul Avatar asked Feb 02 '09 09:02

Henrik Paul


People also ask

What is type erasure in generic?

Type erasure is a process in which compiler replaces a generic parameter with actual class or bridge method. In type erasure, compiler ensures that no extra classes are created and there is no runtime overhead.

What are the two 2 types of Erasure?

- Erasure is a type of alteration in document. It can be classified as chemical erasure and physical erasure.

Why are generics implemented using 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.

What is type erasure and when would you use it?

Type-erasure simply means "erasing" a specific type to a more abstract type in order to do something with the abstract type (like having an array of that abstract type).


1 Answers

The signature of fooMethod(Class<?>) is the same as the signature of fooMethod(Class) after erasure, since the erasure of Class<?> is simply Class (JLS 4.6). Hence, fooMethod(Class) is a subsignature of the fooMethod(Class<?>) but not the opposite (JLS 8.4.2).

For overriding with instance methods you need the overriding method to be a subsignature of the overridden method (JLS 8.4.8.1). This is clearly not the case here.

Now that we have established the fact that your subclass method doesn't override the superclass method according to the JLS, let's look at the runtime implications when type erasure has occured. We now have two methods that look exactly the 'same' (same name, same parameter types) but do not override each other. If they don't override, they must be both available on the subtype as separate methods, but they have identical runtime signatures: conflict. So Java has to disallow it.

Overriding generic parameter types using raw parameter types is allowed because raw types exist just for this reason: they are a convenient mechanism with specific unsound type rules to accommodate interaction with legacy code. So the type system here will decide that the subclass method does override the superclass one, they are identical after type erasure and we can never have a conflict. As a consequence of this libraries can be generified independently of existing non-generic code.

like image 54
eljenso Avatar answered Nov 09 '22 18:11

eljenso