The question is about the following block of code:
public class SomeClass {
public static class A {
public void f(int x) {
System.out.println("1");
}
public void f(Object x) {
System.out.println("2");
}
}
public static class B extends A {
public <T> void f(T x) { // *
System.out.println("3");
}
}
}
Line *
does not compile, with the following error:
Description Resource Path Location Type Name clash: The method f(T) of type SomeClass.B has the same erasure as f(Object) of type SomeClass.A but does not override it
To avoid duplicate:
I've looked at: Type erasure, overriding and generics , Method has the same erasure as another method in type and while I've received an answer (well partially, because I still didn't completely understand it) why there is a compilation error (to avoid ambiguity because of type erasure? is this it?) the main problem is that I don't understand why, if I switch between the two methods f(Object x)
and f(T x)
so the code will be like this:
public class SomeClass {
public static class A {
public void f(int x) {
System.out.println("1");
}
public <T> void f(T x) {
System.out.println("3");
}
}
public static class B extends A {
public void f(Object x) {
System.out.println("2");
}
}
}
I do not receive a compilation error. Why is this happening? What is the key difference for which for the first code I get a compilation error and for the second I don't. Would love some explaining on this, thanks!
One of the answers to one of the questions you linked essentially already addresses this:
For overriding with instance methods you need the overriding method to be a subsignature of the overridden method.
To dig into this a bit more, JLS 8.4.8.1 says this:
An instance method mC declared in or inherited by class C, overrides from C another method mA declared in class A, iff all of the following are true:
[...]
The signature of mC is a subsignature (§8.4.2) of the signature of mA.
A subsignature is defined in JLS 8.4.2:
The signature of a method m1 is a subsignature of the signature of a method m2 if either:
[...]
the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
You're considering the following two signatures:
void f(Object x)
<T> void f(T x)
The erasure of #2 is void f(Object x)
, thus #1 is a subsignature of it. However, vice versa is not true.