1- 为什么要用Java泛型?
泛型是自Java 5版本放入一个概念。引入泛型的概念之前,我们看看Java 5.0版本之前的Java代码片断。
在这个例子中,ArrayList是可以在其中添加,删除,修改列表,并获得了列表的所有元素。
package com.yiibai.tutorial.generics;
import java.util.ArrayList;
public > Tom
Object obj1 = userNames.get(0);
// Cast to String.
String userName1 = (String) obj1;
System.out.println("userName1 = " + userName1);
// And get the second element
// (You know it is a String)
// ==> jerry
String userName2 = (String) userNames.get(1);
System.out.println("userName2 = " + userName2);
// Get the 3rd element (Actually it is an Integer).
// (Error casts happen here).
String userName3 = (String) userNames.get(2);
System.out.println("userName3 = " + userName3);
}
}
在Java 5版本之前的情况:
只包含用于String类型元素的目的创建一个ArrayList对象,但是,添加到这个列表中的元素,程序中并不全是字符串类型(这是完全可能的),当使用这个元素会被转换成String类型,异常将被抛出。
Java泛型实例教程
Java 5引入泛型的概念。借助泛型的帮助下,可以创建一个ArrayList对象只允许包含元素使用字符串的类型,而不是允许包含其它类型的元件。
package com.yiibai.tutorial.generics;
import java.util.ArrayList;
public > userNames = new ArrayList
当创建一个ArrayList
2- 通用类,接口
2.1- 泛型类
下面的例子定义了一个泛型类。KeyValue 是一个包含对键和值的泛型类。
package com.yiibai.tutorial.generics.ci;
public > {
private K key;
private V value;
public KeyValue(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
K,V在KeyValue
下面是使用 KeyValue 类的例子
package com.yiibai.tutorial.generics.ci;
public > entry = new KeyValue
2.2- 继承泛型类
从泛型类扩展一个类可以用于指定泛型参数类型,泛型保留参数或添加泛型参数。
示例1:
package com.yiibai.tutorial.generics.ci;
// This >
// And specify K, V
// K = Integer (Phone Number)
// V = String (Name)
public > {
public PhoneNameEntry(Integer key, String value) {
super(key, value);
}
}
使用PhoneNameEntry示例:
package com.yiibai.tutorial.generics.ci;
public >
示例 2:
package com.yiibai.tutorial.generics.ci;
// This >
// Specify the parameter K is String.
public > extends KeyValue
使用StringAndValueEntry类的示例:
package com.yiibai.tutorial.generics.ci;
public > entry = new StringAndValueEntry
示例3:
package com.yiibai.tutorial.generics.ci;
// This >
// It has added a parameter generics I.
public > extends KeyValue
2.3- 泛型接口
泛型接口:
package com.yiibai.tutorial.generics.ci;
public interface GenericInterface
例如,这个接口的实现:
package com.yiibai.tutorial.generics.ci;
public > implements GenericInterface
2.4- Java不支持通用的Throwable
我们不能创建一个通用类,它是Throwable的子类,因为Java不支持创建这样的类。
编译器的错误信息:
Java泛型实例教程
} catch( Mistake
3- 通用方法
在类或接口中的方法,可以通用。
package com.yiibai.tutorial.generics.m;
import java.util.ArrayList;
import com.yiibai.tutorial.generics.ci.KeyValue;
public >: To say that this method has two parameters K, V
// Method returns K.
public static
例如,使用泛型方法:
package com.yiibai.tutorial.generics.m;
import java.util.ArrayList;
import com.yiibai.tutorial.generics.ci.KeyValue;
public > entry1 = new KeyValue
4- 通用对象初始化
有时候,要初始化一个通用对象:
// Generic Object Initialization
T t = new T; // Error
如果想初始化通用对象,需要传递 Class
package com.yiibai.tutorial.generics.o;
import java.util.Date;
public >
package com.yiibai.tutorial.generics.o;
public > {
private T tobject;
public MyGeneric(Class
package com.yiibai.tutorial.generics.o;
public > mg = new MyGeneric
5- 泛型数组
可以声明泛型数组,但不能初始化通用数组。
// You can declare a generic array of generic.
T myarray;
// But you can not initialize a generic array.
// (This is not allowed).
T myarray = new T[5]; // Error!
应用示例:
package com.yiibai.tutorial.generics.a;
public > {
private T array;
// Contructor.
public GenericArray(T[] array) {
this.array = array;
}
public T getArray {
return array;
}
// Returns the last element of the array.
public T getLastElement {
if (this.array == null || this.array.length == 0) {
return null;
}
return this.array[this.array.length - 1];
}
}
package com.yiibai.tutorial.generics.a;
public > gArray = new GenericArray
回到为什么Java不支持初始化数组通用的问题:
// Why Java don't support to initialize Generic array?
T genericArray = new T[10]; // Error!
// Suppose that Java allows to initialize Generic array:
T tarray = new T[10];
// At the time of compilation, the compiler will consider T as Object.
// This command is equivalent to.
T tarray = new Object[10];
// At runtime of the application, if T is defined as String.
// It means that:
String tarray = new Object[10];
// The above is not allowed. Reason:
// Type mismatch: cannot convert from Object to String
如果想初始化泛型数组,需要传递类
package com.yiibai.tutorial.generics.a;
import java.lang.reflect.Array;
public > {
private Class
package com.yiibai.tutorial.generics.a;
public > garray = new GArray
6- 使用泛型通配符
在通用代码,问号(?),称为通配符,代表一个未知的类型。 通配符参数化类型是一个泛型类型,其中至少一种类型的参数是一个通配符的一个实例。 通配符参数化类型的实例是Collection>, List extends Number>, Comparator super String> 和 Pair
在不同地方的通配符有不同的意义。 例如
Collection> 表示Collection接口的所有实例不管参数的类型。
List extends Number> 所有代表列表类型,其中的元素类型是Number的子类型。
Comparator super String> 表示比较接口使用String的超类型的类型,参数类型的所有实例。
Collection> coll = new ArrayList
一些无效的声明。
// String is not sub> list = new ArrayList
6.1- 带通配符的例子
package com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
public > listString = new ArrayList
package com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
import java.util.List;
public > list) {
for (Object e : list) {
System.out.println(e);
}
}
public static void main(String[] args) {
List
Java泛型实例教程
package com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
public >
// A list containing the elements of type String.
ArrayList
6.3- 通配符不能加入new操作符
通配符参数化类型不会出现在新的表达具体类型。它只是通过Java泛型已使用的任何特定方案有效实施的规则。
// 通配符不能参加new运算符 List extends Object> list= new ArrayList extends Object>; |
|