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 ジェネリック - 型消去 - いつ、何が起こるか)

簡単に言えば、コンパイラは を使用Stringしてすべてのメソッド呼び出しと型変換が機能することを確認し、次に を使用Objectしてバイト コードを生成します。これは、同じシグネチャを持つ 2 つのメソッドがあることを意味します。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 uses type erasure for generics. In your case type is String which Subclass of Object also. And your Bar class allows Object so Nameclash happens.

In your scenario because you are using a non generic legacy class with object as parameter in the extended class I will advice you to change method name or change type of Foo to String `Back to 1.4 days :-)

于 2012-08-24T12:47:55.523 に答える