概述
泛型,即“参数化类型”。 顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参), 然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中, 操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
用法
泛型的定义
泛型方法
要实现不同类型的加法,每种类型都需要重载一个add方法;通过泛型,我们可以复用为一个方法:
/**
* 泛型方法
*/
private static <T extends Number> double add(T a, T b) { //<T> 声明持有泛型类型T,声明该方法为泛型方法
System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue()));
return a.doubleValue() + b.doubleValue();
}
// 用法
add(1,2);
add(1.0,2.0);
/**
* 泛型方法
* <T> 声明持有泛型类型T,声明该方法为泛型方法
* Class<T> 声明泛型T的具体类型,泛型的传递,传递给了 Class<T> 类
* c 泛型T代表的类的对象
* T 泛型类型代表的类型 T
*/
public static <T> T getObject(Class<T> c) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
T t = c.getDeclaredConstructor().newInstance();
return t;
}
泛型类
/**
*泛型类
*/
static class A <T> { // <T> T是type简写,可随意,声明该类持有泛型T的类型
private T var; //var 类型有T指定,即外部指定;
public T getVar() { //返回值有外部指定
return var;
}
public void setVar(T var) { //参数类型有外部指定
this.var = var;
}
}
多元泛型
/**
* 多元泛型
*/
static class MyMap<K,V>{ // 此处指定了两个泛型类型
private K key ; // 此变量的类型由外部决定
private V value ; // 此变量的类型由外部决定
public K getKey(){
return this.key ;
}
public V getValue(){
return this.value ;
}
public void setKey(K key){
this.key = key ;
}
public void setValue(V value){
this.value = value ;
}
}
泛型接口
/**
* 泛型接口
*/
interface IMap<K,V>{
public K getKey();
public V getValue();
public void setKey(K key);
public void setValue(V value);
}
/**
* 泛型接口实现类
*/
static class MyMap2<K,V> implements IMap<K,V>{
private K key ;
private V value ;
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public void setKey(K key) {
this.key = key;
}
@Override
public void setValue(V value) {
this.value = value;
}
}
泛型类型检查
基本类型检查
List<String> list = new ArrayList<String>();
//list.add(1);//泛型提供类型的约束,提供编译前的检查
list.add("a");
泛型的上限和下限
/**
* 泛型类的上限
*/
static class Info<T extends Number>{ // 此处泛型只能是Number的子类
private T var ;
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){
return this.var.toString() ;
}
}
/**
* 泛型类的下限 ,限制只能是Float或者其子类
*/
static void fun(Info<? super Float> test){
System.out.println(test.getVar() + ",,,");
}
泛型的底层原理
Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样。
具体代码:github