Java泛型
1、概述
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,所操作的数据类型被指定为一个参数。
假定有这样一个需求:写一个排序方法,能够对整形数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?这里就可以使用到 Java 泛型。我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。
2、泛型方法
泛型方法在调用时接收任意类型的参数。根据传递给泛型方法的参数类型,编译器(Compiler)适当地处理每一个方法调用。
①规范
形如:
public <E> void doSomething(E e)
泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回值类型之前。
每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。形如:
public <E, F> void handle(E e, F f)
类型参数能被用来声明返回值类型
泛型方法体声明的类型参数只能代表引用型类型,不能是原始类型(int、double、char等)。
泛型可定义有界类型参数。形如:
public <E extends Comparable<T>> void handle(E e)
②实例
不带返回值
import java.util.ArrayList;
/**
* @author Hanlin Wang
*/
public class GenericType {
public static void main(String[] args) {
GenericType genericType = new GenericType();
genericType.showClass(new ArrayList<String>());
genericType.showClass(new String());
genericType.showClass(new Integer(1));
}
public <E> void showClass(E e){
System.out.println(e.getClass());
}
}
运行结果:
class java.util.ArrayList
class java.lang.String
class java.lang.Integer
带返回值
import java.util.ArrayList;
/**
* @author Hanlin Wang
*/
public class GenericType {
public static void main(String[] args) {
GenericType genericType = new GenericType();
System.out.println(genericType.showClass(new ArrayList<String>()));
System.out.println(genericType.showClass(new String("haha")));
System.out.println(genericType.showClass(new Integer(1)));
}
public <E> E showClass(E e){
return e;
}
}
运行结果:
[]
haha
1
多个泛型参数
import java.util.ArrayList;
/**
* @author Hanlin Wang
*/
public class GenericType {
public static void main(String[] args) {
GenericType genericType = new GenericType();
genericType.showClass(new Object(), new String());
}
public <E, F> void showClass(E e, F f){
System.out.println(e.getClass());
System.out.println(f.getClass());
}
}
运行结果:
class java.lang.Object
class java.lang.String
指定泛型界限
/**
* @author Hanlin Wang
*/
public class GenericType {
public static void main(String[] args) {
GenericType genericType = new GenericType();
genericType.show(new String());
}
public <E extends Comparable<E>> void show(E e){
System.out.println("this type has extended Comparable interface");
}
}
代码中的泛型方法参数只能为实现了Comparable接口的类,否则编译不通过。
3、泛型类
①规范
泛型类的声明和非泛型类的声明类似。泛型类后面添加了类型参数声明部分。形如:
class A<E>
泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。
注意!泛型类的类型参数不能指定在静态方法上!否则编译不通过。因为泛型的类型参数使用的前提是有该类的实例对象,在实例对象上传入泛型参数。
②实例
/**
* @author Hanlin Wang
*/
public class GenericType {
public static void main(String[] args) {
A<String> a = new A<String>();
a.show("haha");
}
}
class A<E> {
public void show(E e){
System.out.println(e);
}
}
运行结果:
haha
4、类型通配符
①规范
类型通配符一般是使用?代替具体的类型参数。例如 List < ? > 在逻辑上是List< String >,List< Integer > 等所有 List< 具体类型实参 > 的父类。
定义泛型类的类型形参时,不能使用“?”,只能使用“E”,“T”等形参。将泛型类作为方法的参数或在程序中使用时使用“?”作为类型通配符。
②实例
/**
* @author Hanlin Wang
*/
public class GenericType {
public static void main(String[] args) {
List<String> ls = new ArrayList<String>();
ls.add("asd");
List<Integer> ls2 = new ArrayList<Integer>();
ls2.add(1);
List<Boolean> ls3 = new ArrayList<Boolean>();
ls3.add(true);
show(ls);
show(ls2);
show(ls3);
}
public static void show(List<?> ls){
System.out.println(ls.get(0));
}
}
运行结果:
asd
1
true