web-dev-qa-db-ja.com

「型パラメーターTが型Tを隠している」という警告のトラブルシューティング

Eclipse(最新バージョン)で次のコードについて警告が表示されます。

public interface A<T> extends B<T> {
     public T getObject();
}

警告は「A」の「T」に表示され、「型パラメーターTは型Tを隠しています」と表示されます。

奇妙な部分は、次のコードがエラーや警告を生成しないことです。

public interface A extends B<T> {
     public T getObject();
}

しかし、タイプTが何であるかを伝えながらAを拡張することはできません。

私は完全に混乱しています。なぜこれが起こっているのか誰でも知っていますか?ありがとうございました。

43
nikdeapen

どこかにTという名前のクラスまたはインターフェイスがありますか、またはTを型パラメーターとしてではなく、具体的な型名として使用していますか(たとえば、他の場所を忘れている可能性があります) Tが型パラメーターであることを指定するには、囲みクラスで)?これであなたの問題を再現できます:

class T {  // A concrete type T
}

interface B<T> {  // warning: The type parameter T is hiding the type T
}

interface A<T> extends B<T> {  // warning: The type parameter T is hiding the type T
    T getObject();
}

クラスTを削除すると、消えます。

51
Jesper

最後の答え(質問が古くて閉じていることは知っています)を拡張するために、エラーを理解できる最も単純なケースを提供します。

次のような一般的なメソッドを持つインターフェースを想像してください。

<T> Output<T> doSomething(Input<T> input);

次のようにオーバーライドしようとした場合:

@Override
public <Object> Output<Object> soSomething(Input<Object> input){
    /*..*/
}

コンパイラは次のことを警告します。

型パラメーターObjectは、型Objectを非表示にしています

つまり、「オブジェクト」はここでは汎用ラベルであり、Java.lang.Objectではありません。 Object typeをVまたは任意の任意の文字に変更した場合、それは起こりません。しかし、実際に定義されたクラスと衝突するAppelativeを使用しているので、コンパイラは、このオブジェクトが一般的なObjectクラスとして理解されるものを隠していることを警告します。

4
Whimusical

件名は(「型パラメーターTは型Tを隠している」)であるため、この質問は既に回答されていますが、この警告は常にクラスまたは実際の型「T」があることを意味しないことを付け加えます。すべての回答/コメントが示唆するように、クラスパス(または内部クラス)のどこかで宣言されています。

以下を考慮してください。

public class Cache<K extends Comparable<K>,V> {

  private final  ConcurrentHashMap<K,V> _concurrentMap =  new ConcurrentHashMap<K,V>();

  public <K,V> void add(K key ,V  value){ // Compiler warning - The type parameter V is hiding type V (as also for K)

    _concurrentMap.put(key, value); //Compiler error - K and V passed to add are now being considered different
                                    //from whats declared for _concurrentMap variable
  }

  public V get(K key){
    return _concurrentMap.get(key);
  }

  public int size(){
    return _concurrentMap.size();
  }
}

K、Vはクラスレベルで宣言されているため、メソッドはそれを「継承」します。そのため、同じ警告が表示されます。

以下はもちろん警告とコンパイラエラーを削除します

public <E,F> void add(K key ,V  value){ 
    _concurrentMap.put(key, value); 
}

そして、私の元の方法はこれです。 (私のメソッドに追加のジェネリック型は必要ありません)

public void add(K key ,V  value){ 
    _concurrentMap.put(key, value); 
}
3
Plaiska

私が試します:

public interface B<T> {
    T getObject();

    public  interface A<T> extends B<T>{
        T getObject();
    }
}

eclipse Indigo Service Release 2で、警告もエラーもありません

2