本文主要讨论一下如何声明泛型类,讨论的范围涉及构造函数、静态成员、内部类。
构造函数
泛型的类型参数首先声明在首部:
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<String, Integer> 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<Integer>.getCount // compile-time error
泛型类的静态成员及静态函数是对整个泛型类而言,因此固定类型参数的类进行调用:如Cell<Integer>.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 LinkedCollectionextends AbstractCollection { private class Node { private E element; private Node next = null; private Node(E elt) { element = elt; } } ....}
而对于静态内部类而言,则类型参数则是不可见的,我们必须自己定义内部类的类型参数:
class LinkedCollectionextends AbstractCollection { private static class Node { private T element; private Node next = null; private Node(T elt) { element = elt; } }}
我们在使用外部类中,使用内部类变量时,将外部类类型参数E传入内部类即可:
class LinkedCollectionextends AbstractCollection { private static class Node { .... } private Node first = new Node (null); private Node last = first;}
在软件工程中,比较推荐使用静态内部类,因为它不持有外部类的引用。因此静态内部类可以像类似外部类一样使用,更简单,更好理解。
tips:
如果内部类的的修饰符是public:
对非静态内部类而言,可以这么访问Node:LinkedCollection<E>.Node
而对静态内部类而言:LinkedCollection.Node<E>。