public interface Foo <T> {
void setValue(T value);
}
public abstract class Bar extends JFormattedTextField{
@Override
public void setValue(Object value) {
}
}
public class FooBar extends Bar implements Foo<String>{
@Override //Foo
public void setValue(String aValue) {
// TODO Auto-generated method stub
}
@Override //Bar
public void setValue(Object aValue) {
// TODO Auto-generated method stub
}
}
This results in
Name clash: The method setValue(M) of type Foo has the same erasure as setValue(Object) of type JFormattedTextField but does not override it
Why do I get no love from the compiler and how could I fix it?
This is because of type erasure (see this question: Java generics - type erasure - when and what happens)
In a nutshell: The compiler will use
String
to check that all method calls and type conversions work and then, it will useObject
to generate the byte code. Which means you now have two methods with the same signature:public void setValue(Object aValue)
There is no perfect solution for this. You can make the code above compile by using
Foo<Object>
instead ofFoo<String>
but that's usually not what you want.A workaround is to use an adapter:
Basically what the
adapt()
method should do is create a new instance which implements the correct interface and which maps all method invocations tothis
.