问题引出: 为什么以下代码中getName不需要使用<T>声明,而printA方法要使用<T>声明呢?
public class Test1<T> {
private T name;
public T getName(T name){
return name;
}
public static <T> void printA(T a){
System.out.println(a);
} }
解释:
1.类级别的泛型声明:
在Test1<T>类中,T是在类级别声明的泛型类型参数。这意味着这个类是一个泛型类,可以接收一个类型参数T。一旦你在创建Test1的实例时指定了具体的类型(例如Test1<String>),这个类型就会替代类定义中所有的T。
在Test1<T>类内部,所有没有另外指定泛型类型参数的成员(字段、方法等)默认使用类级别的泛型类型参数T。因此,private T name;和public T getName(T name);中的T自动继承了类级别的泛型类型参数,无需再次声明。
2.方法级别的泛型声明:
printA方法是一个静态方法,并且它有自己的泛型类型参数<T>。这里的<T>是方法级别的泛型声明,它与类级别的泛型T(如果有的话)是独立的。即使Test1类是一个泛型类,静态方法也不能直接使用类级别的泛型类型参数,除非它们是静态泛型成员(这在Java中是不允许的)。
由于printA是一个静态方法,它不能直接访问类级别的泛型类型参数T(如果Test1被实例化为Test1<String>,静态方法并不知道这个具体的类型)。因此,它需要在方法签名中显式地声明自己的泛型类型参数<T>。
3.总结:
- 在泛型类的成员(非静态方法、字段等)中,如果没有另外指定泛型类型参数,它们默认使用类级别的泛型类型参数。
- 静态方法不能直接使用类级别的泛型类型参数,除非它们也是泛型方法(即方法级别有自己的泛型声明)。
这就是为什么getName方法不需要使用<T>声明(因为它自动继承了类级别的泛型类型参数),而printA方法需要使用<T>声明(因为它是静态方法,并且有自己的泛型类型参数)。