为什么会用泛型
集合中如果存储的是Object类型,会引发类型转换问题.
集合建议存储同一类类型数据
什么是泛型
首先泛型是jdk5之后引入的语法.
泛型--->参数化类型. 把类型作为参数传递, 创建类的对象时,可以传入任意类型.
jdk在编译时,就会对类型进行检测
泛型类
泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。
public class Demo<T>
T可以为任意标识符,常见的如T、E、K、V等形式的参数常用于表示泛型
private T key
key这个成员变量的类型为T,T的类型由外部指定
public T getKey()
泛型方法getKey的返回值类型为T,T的类型由外部指定
其实不难看出泛型就是一个规定区间内的各种数据类型。
传入的实参类型需与泛型的类型参数类型相同
泛型的说明有三点:
1.泛型的类型参数只能是类类型,即引用类型
2.泛型的类型参数可以有多个。
3.如果没有定义具体类型,默认为Object
从泛型派生子类
子类也是泛型类,子类和父类的泛型类型要一致 class A<T> extends Demo<T>
子类不是泛型类,父类要明确泛型的数据类型 class A extends Demo<String>
泛型接口
泛型接口与泛型类的定义及使用基本相同。 public interface Demo<T> { }
子类也是泛型类,子类和父类的泛型类型要一致 class A<T> implements Demo<T>{ }
子类不是泛型类,父类要明确泛型的数据类型 public class A implements Demo<String> { }
泛型通配符
? 表示实际传入的参数的泛型类型 ?表示可以是任意的 也称无界通配符
Demo<? extends T> 类型通配符上限 实际传入的类型,只能是T(Number) 获者T的子类。
Demo<? super T> 类型通配符下限 实际传入的类型,只能是T(Number) 获者T的父类
还有一点,集合中如果不添加泛型,默认是可以添加任何类型(引用类型)
public class FanXjin<T> {
private T num;
public T getNum() {
return num;
}
public void setNum(T num) {
this.num = num;
}
public void run(FanXjin<?>obj){
}
public void run2(FanXjin<? extends Number> obj){}
public void run3(FanXjin<? super String> obj){}
public static void main(String[] args) {
FanXjin<String> qq=new FanXjin<>();
FanXjin<Integer> fx=new FanXjin<>();
FanXjin<Object> bob=new FanXjin<>();
fx.run3(bob);
fx.run(qq);
fx.run2(fx);
FanXjin l=new FanXjin();
l.setNum("1");
l.setNum('a');
l.setNum(1);
FanXjin<String> l2=new FanXjin<>();
}
}
类型擦除
泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是,泛型代码能够很好地和之前版本的代码兼容。那是因为,泛到信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为一类型擦除。泛型类被类型擦除后,相应的类型就被替换成 Object 类型或者上限类型.
我们可以通过一些方法看到在运行期间,泛型类就被擦除了,被转换成了相应的引用类型。