为什么 Java 的泛型类型不能用于静态方法?
来看个例子:
class Pair<T> {
private T first;
private T last;
public Pair(T first, T last) {
this.first = first;
this.last = last;
}
public T getFirst() { return this.first; }
public T getLast() { return this.last; }
// 对静态方法使用<T>:
public static Pair<T> create(T first, T last) {
return new Pair<T>(first, last);
}
}
如果在static
方法中写泛型,那么编译器会报错。这是因为普通的方法是通过类的实例来调用的,也就是方法必须创建一个实例出来才能调用(也就是new
),在创建实例的时候会调用实例的构造方法,这时候创建的实例就能知道这个类上面定义的<T>
类型了。
而静态方法呢,不需要创建一个实例就能调用,不创建实例也就没有调用构造方法,那么创建出来的实例就无法 get 到这个类的<T>
类型,因此相当于盲人摸象。
看下面的定义:
Pair<String> p = new Pair<>("Hello", "world"); //创建实例时已经知道<T>是String类型
String first = p.getFirst();
Pair.create(...); //如果 create 是类 Pair 的静态方法,则并不清楚<T>的具体类型
总结:静态方法由于随着类的加载而加载,不能访问类的泛型(因为在创建对象的时候才确定),因此必须定义自己的泛型类型。
那么怎么让泛型类型适用于静态方法呢?
// 静态 create 泛型方法
public static <T> Pair<T> create(T first, T last) {
return new Pair<T>(first, last);
}
上面,在 static 后面也加上<T>
编译器就不会报错了,但实际上这个<T>
和Pair<T>
类型的<T>
已经没有任何关系了。
将静态方法的泛型类型和实例类型的泛型类型区分开:
// 静态 create 泛型方法
// 要这样,K不与类定义的<T>冲突
public static <K> Pair<K> create(K first, K last) {
return new Pair<K>(first, last);
}
打破零回复