Skip to content
Advertisement

Why can’t I add a type parameter to an overriding method?

I need to implement a method from a class Foo, in my subclass Bar:

JavaScript

As you can see, my method would benefit from a type parameter:

JavaScript

(I could also use raw types because I know it’ll work, but everything I’ve read says you really shouldn’t do that)

Unfortunately, this is illegal – my method foo in Bar “clashes with foo() in Foo; both methods have the same erasure, yet neither overrides the other”.

Which seems odd, given that my type parameter does not alter the parameters or return type of foo – any place it is okay to use Foo.foo in, it is also okay to use my (illegal) Bar.foo in.

My ugly hack of a workaround has, up until this point, been to just write a whole new (parameterized) method:

JavaScript

I have two questions:

  1. Why does adding a type parameter to a method prevent it from overriding an unparameterized method in its superclass?
  2. Is there a better way to get the behavior I want?

Advertisement

Answer

See JLS 8.4.2:

8.4.2. Method Signature

Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.

The signature of a method m1 is a subsignature of the signature of a method m2 if either:

  • m2 has the same signature as m1, or
  • the signature of m1 is the same as the erasure (§4.6) of the signature of m2.

Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.

Because type parameters are part of the method signature, you can’t add or remove type parameters in overriding methods.

My ugly hack of a workaround…

Yes, it’s ugly, but this is the right way to do it.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement