首页 > 解决方案 > 泛型类名称与泛型参数相同

问题描述

对于下面的代码

public class T<T> {
    public String toString() {
        return "Generic Types!";
    }
    public void run(T var) {
        Integer repeatCount = 12_57;
        System.out.println("debug: " + repeatCount + ", " + var.toString());
    }
    public static void main(String[] args) {
        System.out.println("Hello, World!");
        T<String> t = new T();
        t.run(t);
    }
}

该行public class T<T>给出警告The type parameter T is hiding the type T<T>

该行 T<String> t = new T()给出了一个错误cannot make a static reference to non-static type T

如果我更改public class T<T>public class T<K>. 但我不明白原因。输出 :

Hello, World!
debug: 1257, Generic Types!

我是泛型概念的新手,有人可以解释一下上面的代码有什么问题吗?

标签: javagenerics

解决方案


在这里,您声明了一个T带有泛型参数的类T。在这个类中,T现在可以参考两件事:

  1. 泛型类
  2. 泛型参数

这里用两个箭头表示:

public class T<T>
             ^ ^
             1 2

那么当你T在这个类里面写的时候,Java怎么知道你的意思是什么意思呢?1和2都是类型!根据语言规则,意思 2 是受欢迎的。

如果您对它的规则感兴趣,请参阅 JLS 的§6.4.1

名为 n 的类型的声明 d 会遮蔽任何其他名为 n 的类型的声明,这些类型在 d 出现在整个 d 范围内的点上。

第二个T在第一个的范围内T,所以遮住了它。

您对类内部的所有引用都T指的是第二个T,即泛型参数。为什么泛型参数T是非静态的,请参阅泛型类中的静态方法?泛型 - 为什么类类型变量在静态上下文中无效?

但是,即使泛型参数T是静态的,它也不是泛型的,并且您将无法像 in 那样对其进行参数化T<String>(实际上您不能将任何泛型参数设为泛型)。

除了重命名类名(first T)之外,您还可以使用完全限定名来引用它:

yourpackagename.T

推荐阅读