泛型的概述
什么是泛型:
泛型就是"类型参数化"
- 就是把元素的类型设计成一个参数,这个类型参数就叫泛型
泛型是jdk5.0中提出来的新特性
为什么提出来泛型?
在jdk5之前我们没有提出泛型的时候,那个时候我们在集合中存储对象的时候就是存储的Object类型,这个时候我们给集合中加入对象的时候只要是Object子类类型对象都可以加入集合中,我们也就可以说任何的对象都可以放入我们的集合中,因为所有的类都直接或者间接的继承了Object类,这个时候我们在集合中装入数据加入了很多类型的数据的时候,这个时候装的很方便,但是这个时候我们如果要取出来使用这个集合中元素的独有方法,这个时候由于我们在集合中存储对象的时候都是自动向上转型为了Object类型,这个时候我们要使用这个集合中元素的独有方法这个时候我们肯定就要使用向下转型,将我们的对象从Object类型转为我们的集合元素的实际类型,但是这个时候由于我们的存储数据的不确定性,就有可能出现类型转化异常(ClassCastException),这个时候转型起来的时候会很麻烦
泛型的声明和和泛型的作用:
泛型就是允许在定义类,接口时通过一个标识表示类中的摸个属性的类型,或者是某个方法的返回值类型,也可能是某个方法的参数类型,这个类型参数将在使用时(例如:继承或者实现这个接口,用这个类类型声明变量或者用这个类创建对象时)确定
- 我们将传入实际的类型参数(也就是实际传入的泛型类型)称之为类型实参
泛型的声明和泛型的作用的总结:
- 泛型 — 是定义类,接口时的一个标识
- 通过泛型 ---- 标识该类,接口中的某个属性,某个方法的返回值,某个方法的参数类型等等
- 泛型在继承或实现这个接口,用这个类声明变量,或者创建对象时确定
- 通过传入的实际参数就确定了泛型 — 这个传入的实际参数我们又称之为类型实参
在jdk1.5中我们提出泛型的时候java官方就为改写了集合框架中的所有接口和类,为这些类和接口提供了泛型支持
这里我们举一个例子,如果我们没有泛型时如果我们要创建一个集合专门放学生的成绩,并且装入集合中之后我们还要通过向下转型将我们的Object类型的元素向下转型为Integer类型(这个时候如果我们存储对象的时候存储错了,比如我们如果存储了一个String类型的数据,这个时候编译不会出错,但是我们向下转型就会出现错误)
package com.ffyc.javaoop.day19;
import java.util.ArrayList;
import java.util.Iterator;
public class Chengji {
public static void main(String[] args) {
ArrayList a = new ArrayList();
a.add(45);
a.add(77);
a.add(49);
a.add("abc");
a.add(99);
Iterator iterator = a.iterator();
while(iterator.hasNext()){
Object next = iterator.next();
Integer i = (Integer)next;
}
}
}
如果在这个时候我们使用泛型的话就不会出现这样的类型转换异常的问题,因为这个时候我们如果制定了泛型,这个时候如果我们添加到集合的元素不是指定类型的话,这个时候编译就会出错
- 但是要注意这里我们指定泛型时
- 如果是使用父类的引用指向子类的对象,或者使用子类引用指向子类的对象
- 这时候我们指定泛型的时候可以前面指定后面不指定,当然两面都制定肯定也可以,但是不可以后面指定前面不指定
- 因为我们编译器看的是前面,当我们前面制定了泛型的时候,这个时候我们编译器就对存储的元素类型进行了选择,如果不是指定类型的元素连编译都不会通过,这个时候就算运行期还是以Object类型来存储,但是这个时候都不影响了,因为我们这个时候这个集合中存储的对象肯定都为一个指定类型的元素
- 但不能指定运行时又不指定编译时,如果指定运行时而不指定编译时,这个时候还不如什么都不指定,这个时候我们编译器不仅不会检测,并且如果我们编译器输错了,这个时候编译可以通过但是运行有可能会出错 – -- 就相当于把我们自己骗了
|