简单做一个泛型知识骨架,有时间在添肉。
前阵子公司技术分享,学习到了java8的一些新特性,给我感觉是编码变得越来越“简单”,并不是思想简单,而是实现上,像lambda,stream,编码变得越来越简单明了,的确,回想接口,继承,简单点说都是为了复用代码,泛型也一样,可能一段逻辑并不在乎你是什么类,你来了只要符合我的规定,我就可以让你执行。
一、是什么
泛型,jdk1.5引入,即参数化类型,在声明的时候不规定实际的类型,将类型做为参数在方法调用时传递,典型的就是集合相关类
二、使用范围
泛型类:
class<T>{}
class<T,U>{}
泛型方法:
public <T>void test(T t){}
只有在方法的返回值前面加了<>才表名为泛型方法,否则即使某个方法的参数列表含有泛型参数,也只是个普通方法,泛型方法是独立于类存在的,可以定义在普通类中,所以说泛型方法中的参数与类中的参数并无关系,即使同名也一样。
并且泛型方法具有自动推断类型功能。关于类型推断,额,先欠着,(ps:类型推断网址)
泛型接口:
参考Comparable
三、通配符与类型限定
类型限定:extends
限定为类
限定为接口
限定为其它类
一个类型变量或者通配符可以有多个限定,同java一样,单继承多实现,多个限定之间用 & 分隔,并且如果既有接口又有父类,父类在第一个参数位置,别问为什么,老爹最重要,
通配符:?
?
? extends String String及其子类
? super String String及其父类
以前总是在纠结,T明明就可以代表任意类型了,为什么还会有通配符,通配符不也是代表任意类型吗?先看例子:
情况1:List<?> list = new ArrayList();
list.add("11");
list.add(11);
情况2:list.removeAll(Collection<?> c);
情况3:ListContainer<?> container = null;
List<?> list = null;
...
list = ListContainer<ArrayList>(new ArrayList());
以上情况下,可以很好的阐述通配符的存在意义了。
四、泛型擦除
泛型只存在于编译阶段,虚拟机中没有泛型类型的对象–-所有对象都是普通的类,无论我们什么时候定义的泛型类型,
在虚拟机中都自动转换成了一个相应的原始类型.原始类型就是擦除类型变量,并替换为第一个限
定符类型(没有限定符用Object替换)后的泛型类型名,兼容jdk1.5之前的(ps:所以说我们没有做的事别人做了,并不是没有做,故c程序的运行速度不会因为使用泛型而加快)