Java泛型类和泛型方法(附带实例)
Java 程序中,你可能经常需要实现适用于多种类型的类和方法。例如,ArrayList<T>可以存储任意类 T 的元素。我们称 ArrayList 类为泛型(generic),T 是类型参数(type parameter)。
作为一个简单的示例,下面考虑这个用来存储键值对的类:
可以通过用类型替换的方式,替换类型变量来实例化(instantiate)泛型类。例如,Entry<String,Integer> 是一个普通类,具有方法 String getKey() 和 Integer getValue()。
泛型方法可以是常规类或泛型类中的方法。下面是一个非泛型类中泛型方法的示例:
调用泛型方法时,不需要指定类型参数。它是从方法参数和返回类型中推导出来的。例如,在调用 Arrays.swap(friends, 0, 1) 中,friends 的类型是 String[],编译器可以推导出 T 应该是 String。
Java泛型类
泛型类(generic class)是具有一个或多个类型参数(type parameter)的类。作为一个简单的示例,下面考虑这个用来存储键值对的类:
public class Entry<K, V> { private K key; private V value; public Entry(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }如你所见,类型参数 K 和 V 在类名后的尖括号内指定。在类成员的定义中,它们被用作实例变量、方法参数和返回值的类型。
可以通过用类型替换的方式,替换类型变量来实例化(instantiate)泛型类。例如,Entry<String,Integer> 是一个普通类,具有方法 String getKey() 和 Integer getValue()。
当构造泛型类的对象时,可以在构造器中省略类型参数。例如:警告,类型参数不能用基本类型实例化。例如,Entry<String, int> 在 Java 中无效。
Entry<String, Integer> entry = new Entry<>("Fred", 42); // Same as new Entry<String, Integer>("Fred", 42)需要注意的是,在构造参数之前仍然需要提供一对空的尖括号。有人把这对空的尖括号称为菱形(diamond)。当使用菱形语法时,构造器的类型参数将被推导得出。
Java泛型方法
就像泛型类是带有类型参数的类一样,泛型方法(generic method)是一个带有类型参数的方法。泛型方法可以是常规类或泛型类中的方法。下面是一个非泛型类中泛型方法的示例:
public class Arrays { public static <T> void swap(T[] array, int i, int j) { T temp = array[i]; array[i] = array[j]; array[j] = temp; } }这个 swap() 方法可用于交换任意数组中的元素,只要数组元素类型不是基本类型:
String[] friends = ...; Arrays.swap(friends, 0, 1);当声明泛型方法时,类型参数被放置在修饰符(如 public 和 static)之后和返回类型之前。
调用泛型方法时,不需要指定类型参数。它是从方法参数和返回类型中推导出来的。例如,在调用 Arrays.swap(friends, 0, 1) 中,friends 的类型是 String[],编译器可以推导出 T 应该是 String。