实现具有相同方法名称的接口和抽象类,从而导致泛型名称冲突


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 天 :-(

相关内容

  • 没有找到相关文章

最新更新