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(,但不 覆盖它
为什么我没有得到编译器的爱,我该如何解决它?
这是因为类型擦除(请参阅此问题:Java 泛型 - 类型擦除 - 何时发生(
简而言之:编译器将使用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
。
Java对泛型使用类型擦除。在您的情况下,类型是字符串,该子类也是对象的子类。并且您的 Bar 类允许 Object,因此会发生名称冲突。
在您的场景中,由于您在扩展类中使用了带有对象作为参数的非通用遗留类,因此我建议您更改方法名称或将Foo
类型更改为String
'回到 1.4 天 :-(