3
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) 具有相同的擦除,但不会覆盖它

为什么我没有得到编译器的爱,我该如何解决它?

4

2 回答 2

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.

于 2012-08-24T12:50:21.673 回答
0

Java 对泛型使用类型擦除。在您的情况下,类型是 String ,它也是 Object 的子类。并且您的 Bar 类允许 Object 所以 Nameclash 发生。

在您的场景中,因为您在扩展类中使用带有对象作为参数的非通用遗留类,我会建议您更改方法名称或将类型更改FooString`Back to 1.4 days :-)

于 2012-08-24T12:47:55.523 回答