本文主要讨论一下如何声明泛型类,讨论的范围涉及构造函数、静态成员、内部类。
构造函数
泛型的类型参数首先声明在首部:
public class Pair {
private final T first;
private final U second;
private static int count = 0;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst {
return first;
}
public U getSecond {
return second;
}
public static void main(String[] args) {
Pair pair = new Pair(2,"generic test"); // 1 line
System.out.println(pair.getFirst);
System.out.println(pair.getSecond);
}
}
当我们调用构造函数时,真实的泛型参数将被传入,如代码中的“1 line”这行所示。
Pair pair = new Pair("one",2);
构造函数也可以向上述这么写,但会提示warning。
甚至我们还可以这么写:
Pair pair = new Pair("one",2);
这个不会报错,也会提示warning。
静态成员
对于静态成员而言,是类可见的,所以
public class Cell {
private final int id;
private final T value;
private static int count = 0;
private static synchronized int nextId {
return count++;
}
public Cell(T value) {
this.value = value;
id = nextId;
}
public T getValue {
return value;
}
public int getId {
return id;
}
public static synchronized int getCount {
return count;
}
}
我们可以通过Cell.getCount直接获取静态成员,并不需要指定类型参数。
如果指定类型参数反而报错:
Cell.getCount // compile-time error
泛型类的静态成员及静态函数是对整个泛型类而言,因此固定类型参数的类进行调用:如Cell.getCount。
同样的,像下面这样的代码也是错误的:
class Cell2 {
private final T value;
private static List values = new ArrayList; // illegal public Cell(T value) { this.value=value; values.add(value); } public T getValue { return value; }
public static List getValues { return values; } // illegal
}
内部类
对非静态内部类而言,其外部类(outer class)的类型参数对它是可见的。因此内部类可以使用外部类的类型参数:
public class LinkedCollection extends AbstractCollection {
private class Node {
private E element;
private Node next = null;
private Node(E elt) { element = elt; }
}
....
}
而对于静态内部类而言,则类型参数则是不可见的,我们必须自己定义内部类的类型参数:
class LinkedCollection extends AbstractCollection {
private static class Node {
private T element;
private Node next = null;
private Node(T elt) { element = elt; }
}
}
我们在使用外部类中,使用内部类变量时,将外部类类型参数E传入内部类即可:
class LinkedCollection extends AbstractCollection {
private static class Node {
....
}
private Node first = new Node(null);
private Node last = first;
}
在软件工程中,比较推荐使用静态内部类,因为它不持有外部类的引用。因此静态内部类可以像类似外部类一样使用,更简单,更好理解。
tips:
如果内部类的的修饰符是public:
对非静态内部类而言,可以这么访问Node:LinkedCollection.Node
而对静态内部类而言:LinkedCollection.Node。