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
}
}
这导致
名称冲突:Foo类型的方法setValue(M)具有相同的名称 擦除为JFormattedTextField类型的setValue(Object)但不是 覆盖它
为什么我不喜欢编译器,我该如何解决?
答案 0 :(得分:3)
这是因为类型擦除(请参阅此问题:Java generics - type erasure - when and what happens)
简而言之:编译器将使用String
检查所有方法调用和类型转换是否有效,然后,它将使用Object
生成字节代码。这意味着您现在有两个具有相同签名的方法:public void setValue(Object aValue)
没有完美的解决方案。你可以使用Foo<Object>
而不是Foo<String>
来编译上面的代码,但这通常不是你想要的。
解决方法是使用适配器:
public class FooBar extends Bar {
public Foo<String> adapt() {
return new Foo<String>() {
public void setValue(String value) {
FooBar.this.setValue( value );
}
}
}
}
基本上adapt()
方法应该做的是创建一个实现正确接口的新实例,并将所有方法调用映射到this
。
答案 1 :(得分:0)
Java使用类型擦除来表示泛型。在你的情况下,类型是String,它也是Object的子类。而你的Bar类允许对象,因此Nameclash会发生。
在您的场景中,因为您在扩展类中使用了带有object作为参数的非泛型遗留类,我将建议您更改方法名称或将Foo
的类型更改为String
`返回1.4天:-)