1.引言
Java从JDK 1.5之后开始支持泛型。为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即在语法上支持泛型,但是在编译阶段会进行“类型擦除”,将所有的泛型表示(尖括号里的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样。
2.引入泛型的原因
泛型的本质是为了参数化类型(即在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型的使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
引入泛型的意义在于:适用于多种数据类型执行相同的代码
例1:
如下列代码如果没有泛型,要实现不同类型的加法,每种类型都要重载一个add()方法:
private static int add(int a, int b) {
System.out.println(a + "+" + b + "=" + (a + b));
return a + b;
}
private static float add(float a, float b) {
System.out.println(a + "+" + b + "=" + (a + b));
return a + b;
}
private static double add(double a, double b) {
System.out.println(a + "+" + b + "=" + (a + b));
return a + b;
}
通过泛型,可以复用为一个方法,泛型中的类型在使用时指定,不需要强制类型转换
如:
private static <T extends Number> double add(T a, T b) {
System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue()));
return a.doubleValue() + b.doubleValue();
}
例2:
在使用下述List中,List中的元素都是Object类型(无法约束其中的类型),所以在取出元素的时候需要人文强制类型转换到具体的目标类型,并且很容易出现异常
List list = new ArrayList();
list.add("xxString");
list.add(100d);
list.add(new Person());
引入泛型,提供类型的约束,并提供编译前的检查
List<String> list = new ArrayList<String>();
// list中只能放String, 不能放其它类型的元素
3.泛型的基本使用
泛型的使用包括三种:泛型类、泛型接口、泛型方法
3.1泛型类
简单泛型类
/**
* 简单的泛型类
*/
class Point<T>{ //此处的T是Type的简称
private T var; //var的类型由T指定,即由外部指定
public T getVar(){ //方法返回值的类型也有T指定
return var; //传入参数的类型也由外部指定
}
public void setVar(T var){
this.var=var;
}
}
public class GenericDemo {
public static void main(String[] args) {
Point<String> p = new Point<String>();
p.setVar("hello world");
System.out.println("字符串长度:"+p.getVar().length());
}
}
多元泛型类
/**
* 多元泛型类
*/
class Notepad<K,V>{ // 指定两个泛型类型
private K key; //两个变量的类型都有外部决定
private V 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;
}
}
public class GenericDemo02 {
public static void main(String[] args) {
Notepad<String, Integer> notepad = new Notepad<String,Integer>();
notepad.setKey("张三");
notepad.setValue(25);
System.out.println("姓名:"+notepad.getKey()+"年龄:"+notepad.getValue());
}
}
泛型接口
/**
* 简单的泛型接口
*/
interface Info<T>{ //泛型接口
public T getVar(); //定义抽象方法,抽象方法的返回值就是泛型类型
}
class InfoImpl<T> implements Info<T>{
private T var;
public InfoImpl(T var){
this.setVar(var);
}
public void setVar(T var){
this.var=var;
}
public T getVar(){
return this.var;
}
}
public class GenericDemo3 {
public static void main(String[] args) {
InfoImpl<String> in = new InfoImpl<String>("张三");
System.out.println(in.getVar());
}
}
参考:
Java 基础 - 泛型机制详解