故障排除"类型参数T隐藏类型T"警告

nik*_*pen 44 java generics warnings

我在eclipse(最新版本)中收到以下代码的警告.

public interface A<T> extends B<T> {
     public T getObject();
}
Run Code Online (Sandbox Code Playgroud)

警告出现在'A'中的'T'处,并显示:"类型参数T隐藏类型T".

奇怪的是,以下代码不会生成任何错误或警告.

public interface A extends B<T> {
     public T getObject();
}
Run Code Online (Sandbox Code Playgroud)

但是现在我不能在告诉它T是什么类型时扩展A.

我完全糊涂了.任何人都知道为什么会这样吗?谢谢.

Jes*_*per 52

你在某个地方有一个类或接口名称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();
}
Run Code Online (Sandbox Code Playgroud)

如果我删除了类T,它就会消失.

  • 当内部泛型类重复使用与封闭(也是通用)类相同的Type参数时,这也会发生. (15认同)
  • 就是这样,谢谢!事实证明我偶然导入了一个与type参数同名的类.我取出了导入,它工作正常. (2认同)

小智 5

即使这个问题已经回答,由于主题行是关于 ("The type parameter T is hidden the type 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

因为 K ,V 是在类级别声明的,所以 add 方法也“继承”了它。所以你最终会得到同样的警告。

下面当然删除警告和编译器错误

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

而我原来的方法是这样的。(我的方法不需要额外的泛型类型)

public void add(K key ,V  value){ 
    _concurrentMap.put(key, value); 
}
Run Code Online (Sandbox Code Playgroud)


Whi*_*cal 5

只是为了扩展最后一个答案(我知道问题已经解决),我将提供一个最简单的情况,您可以了解该错误:

想象一下具有通用方法的接口,例如:

<T> Output<T> doSomething(Input<T> input);
Run Code Online (Sandbox Code Playgroud)

如果尝试覆盖为:

@Override
public <Object> Output<Object> soSomething(Input<Object> input){
    /*..*/
}
Run Code Online (Sandbox Code Playgroud)

编译器警告您:

类型参数Object隐藏类型Object

这意味着“对象”在这里是通用标签,而不是java.lang.Object。如果将对象类型更改为V或任意字母,则不会发生。但是您使用的是与实际定义的类相冲突的appelative,因此编译器会警告您您的此Object隐藏了本来可以理解为普通Object类的东西。

  • 由于答案显示的顺序不是固定的,“最后一个答案”并不能真正指出您的意思。 (2认同)