关于Java泛型
泛型介绍
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方法要使用泛型能力,就必须使其成为泛型方法。