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 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 KeyValue2.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 KeyValue2.3- 泛型接口泛型接口: package com.yiibai.tutorial.generics.ci;
public interface GenericInterface例如,这个接口的实现: package com.yiibai.tutorial.generics.ci;
public > implements GenericInterface2.4- Java不支持通用的Throwable我们不能创建一个通用类,它是Throwable的子类,因为Java不支持创建这样的类。 编译器的错误信息: } catch( Mistake3- 通用方法在类或接口中的方法,可以通用。 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 KeyValue4- 通用对象初始化有时候,要初始化一个通用对象: // 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(Classpackage com.yiibai.tutorial.generics.o;
public > mg = new MyGeneric5- 泛型数组可以声明泛型数组,但不能初始化通用数组。 // 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 Classpackage com.yiibai.tutorial.generics.a;
public > garray = new GArray6- 使用泛型通配符在通用代码,问号(?),称为通配符,代表一个未知的类型。 通配符参数化类型是一个泛型类型,其中至少一种类型的参数是一个通配符的一个实例。 通配符参数化类型的实例是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 ArrayList6.1- 带通配符的例子package com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
public > listString = new ArrayListpackage 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) {
Listpackage com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
public >
// A list containing the elements of type String.
ArrayList6.3- 通配符不能加入new操作符通配符参数化类型不会出现在新的表达具体类型。它只是通过Java泛型已使用的任何特定方案有效实施的规则。 // 通配符不能参加new运算符 List extends Object> list= new ArrayList extends Object>;
|