Java 泛型 (General Type) 需要知道的几点

什么是泛型(Generic Type)?

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

Java 在 J2SE 1.5 版本添加了对泛型的支持。为什么需要泛型呢?在JAVA中,总是不可避免的需要 downcast ,但是每个 downcast 对于ClassCastException 而言都是潜在的危险,应当尽量避免它们。而 J2SE 1.5之前即便再优良的设计也不可避免。例如:

class Hashtable {
Object put(Object key, Object value) {...}
Object get(Object key) {...}
...
}
class Test {
public static void main(String[] args) {
Hashtable h = new Hashtable();
h.put(new Integer(0), "value");
String s = (String)h.get(new Integer(0));
System.out.println(s);
}
}

class Hashtable {  Object put(Object key, Object value) {...}  Object get(Object key) {...}  ...}class Test {  public static void main(String[] args) {    Hashtable h = new Hashtable();    h.put(new Integer(0), "value");    String s = (String)h.get(new Integer(0));    System.out.println(s);  }}

如果使用泛型,我们可以这么解决问题:

class Hashtable<Key, Value> {

...

Value put(Key k, Value v) {...}

Value get(Key k) {...}

}

class Test {

public static void main(String[] args) {

Hashtable<Integer, String> h = new Hashtable<Integer, String>();

h.put(new Integer(0), "value");

...

}

}

略过泛型的具体使用介绍,我们来看看几件必须知道的事情:

1. 必须用引用类型进行实例化,基本类型不起作用。
因此,在上面示例中,无法完成创建从 int 映射到 String 的 Hashtable 。

2.泛型不支持类继承

List<Number> numbers = new ArrayList<Integer>(); // will not compile

List<Long> list = new ArrayList<Long>();

List<Number> numbers = list; // this will not compile

3.在JAVA中,泛型的实现是擦除法。

编译器在生成类文件时基本上会抛开参数化类的大量类型信息。也就是说编译器会将泛型类型以其父类代替,如String变成了Object等。
尽管不能将 List<Integer> 赋给 List<Number>,但是

new List<Number>().getClass() == new List<Integer>().getClass()

4.不能创建泛型数组

T[] arr = new T[10];// this code will not compile

List<Integer>[] array = new List<Integer>[10]; // does not compile

因为数组本身是支持类继承的:

Number[] a = new Number[10];

a[1] = Integer.valueOf(1);

4.不能创建泛型数组
T[] arr = new T[10];// this code will not compile

List<Integer>[] array = new List<Integer>[10]; // does not compile

因为数组本身是支持类继承的。

Number[] a = new Number[10]; a[1] = Integer.valueOf(1);

5.使用通配符
5.1 <? extends E>

java.util.List.java

boolean addAll(Collection<? extends E> c);

List<? extends Long> list = new ArrayList();

List<Long> longlist = new ArrayList();

list = longlist;
5.2 <? super E>

List<? super Long> list = new ArrayList();

List<Number> longlist = new ArrayList();

list = longlist;

6. Multiple Bounds

例如你定义约束是这个类必须是Number,并且应该继承i

public static <T extends Number & Comparable<? super T>> int compareNumbers(T t1, T t2){

return t1.compareTo(t2);

}

public static <T extends String & Number > int compareNumbers(T t1, T t2) // does not work..can't have two classes

public static <T extends Comparable<? super T> & Number > int compareNumbers(T t1, T t2) // does not work..

public static <T extends CharSequence & Comparable<T>> int compareNumbers(T t1, T t2)// works..multiple interfaces