Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding a generic method by a generic one in Java

Tags:

java

generics

Angelica Langer says in her FAQ about generics (see Technicalities.FAQ822):

If the methods have type parameters with different bounds , then they do not override, because the methods have signatures that are not override-equivalent. Remember, the type parameter bounds are part of a generic method's signature.

Example (of generic subtype methods overloading generic supertype methods; not recommended):

class Super {
   public <T> void set( T arg) { ... }
   public <T> T get() { ... }
}
class Sub extends Super {
   public <S extends Number > void set( S arg) { ... } // overloads
   public <S extends Number > S get() { ... }         // overloads
}

I don't understand why the get method is overloaded in class Sub. For what I know it should be a compile time error because get has the same signature in both Sub and Super (the return type is not part of it).

What confuse me even more is that the IDE I'm using to test the code (IntelliJ IDEA 14.0.3) highlights get in Sub as a compilation error with the next message:

'get()' in 'Sub' clashes with 'get()' in 'Super'; both methods have the same erasure, yet neither overrides the other.

But when I run the program it compiles and executes without problems. I suppose there is some kind of bug in IntelliJ when it analyzes the code, and what is correct is what Angelica tells in her FAQ. But I can't catch the point.

like image 709
Bleyder Avatar asked Feb 27 '15 13:02

Bleyder


1 Answers

According to JLS, method signature does not include return type but only the method name and the type of its parameters. This means when compiling Super and Sub, a compile error should return as Sub.get() has the same erasure as Super.get() but neither overrides nor overloads Super.get(). It cannot override because the bounded type X extends Number is not a subtype of the type X, and it cannot overload because the return type is not part of a method signature. Sub.set overloads Super.set in this case.

As to why you can compile and run it. If you are running Java 6, then there is a known bug in Java 6 that would compile Super and Sub. In Java 7 this is fixed and would not be allowed.

like image 156
Peter Avatar answered Nov 04 '22 16:11

Peter