泛型介绍
Java泛型相当于是C++中的模板。
它使编写的代码可以被很多不同类型的对象所重用。
泛型类
泛型类就是具有一个或多个类型变量的类。
将类型变量用尖括号(< >)括起来,放在类名后面。
每一个类型变量声明部分包含一个或多个类型变量,变量间用逗号隔开。
泛型类实例代码:
1 public class demo<T> {
2 // t这个成员变量的类型为T,T的类型由外部指定
3 private T t;
4
5 // 泛型构造方法形参key的类型也为T,T的类型由外部指定
6 public demo(T t) {
7 this.t = t;
8 }
9
10 // 泛型方法get的返回值类型为T,T的类型由外部指定
11 public T get() {
12 return t;
13 }
14
15 public static void main(String[] args) {
16 //传入的实参类型需与泛型的类型参数类型相同,即为Integer
17 demo<Integer> d1 = new demo<Integer>(123);
18 System.out.println("泛型Integer:" + d1.get());
19
20 //传入的实参类型需与泛型的类型参数类型相同,即为String
21 demo<String> d2 = new demo<String>("abc");
22 System.out.println("泛型String:" + d2.get());
23 }
24 }
运行结果:
泛型Integer:123
泛型String:abc
泛型类在实例化类的时候指明泛型的具体类型。
对象为Integer类型时,类里的变量都为Integer类型。
对象为String类型时,类里的变量都为String类型。
泛型方法
泛型方法可以定义在普通类中,也可以定义在泛型类中。
泛型方法类型变量放在修饰符的后面,返回类型的前面。
泛型方法实例代码:
1 public class demo {
2 // 泛型方法 get
3 public static <E> void get(E[] e) {
4 // 输出数组元素
5 for (int i = 0; i < e.length; i++) {
6 System.out.printf(e[i] + " ");
7 }
8 }
9
10 public static void main(String args[]) {
11 // 创建不同类型数组: Integer,Double,Character,String
12 Integer[] i = { 1, 2, 3, 4, 5 };
13 Double[] d = { 1.1, 2.2, 3.3, 4.4, 5.5 };
14 Character[] c = { 'H', 'E', 'L', 'L', 'O' };
15 String[] s = { "W", "O", "R", "L", "D" };
16
17 System.out.println("整型数组元素为:");
18 demo.get(i); // 传递一个整型数组
19
20 System.out.println("\n双精度型数组元素为:");
21 demo.get(d); // 传递一个双精度型数组
22
23 System.out.println("\n字符型数组元素为:");
24 demo.get(c); // 传递一个字符型数组
25
26 System.out.println("\n字符串型数组元素为:");
27 demo.get(s); // 传递一个字符串型数组
28 }
29 }
运行结果:
整型数组元素为:
1 2 3 4 5
双精度型数组元素为:
1.1 2.2 3.3 4.4 5.5
字符型数组元素为:
H E L L O
字符串型数组元素为:
W O R L D
泛型方法是在调用方法的时候指明泛型的具体类型。
泛型的约束与局限性
1.不能用基本的类型实例化类型参数
2.运行时类型查询只适用于原始类型
3.不能创建参数化类型的数组
4.Varargs警告
5.不能实例化类型变量
6.不能构造泛型数组
7.泛型类的静态上下文类型变量无效
8.不能抛出或捕获泛型类的实例
9.可以消除对受查异常的检查
10.注意擦除后的冲突
这10点我会在以后的随笔里详细进行讨论
总结
无论何时,如果你能做到,你就该尽量使用泛型方法。也就是说,如果使用泛型方法将整个类泛型化,那么就应该使用泛型方法。另外对于一个static的方法而已,无法访问泛型类型的参数。所以如果static方法要使用泛型能力,就必须使其成为泛型方法。