泛型在java中有很重要的地位,无论是开源框架还是JDK源码都能看到它。
毫不夸张的说,泛型是通用设计上必不可少的元素,所以真正理解与正确使用泛型,是一门必修课。但是出初学者想学习泛型必不可少的需要先了解集合体系
一 、Collection集合
1.1集合概述
集合:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?
数组的长度是固定的。集合的长度是可变的。
数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类 型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。
1.2集合框架
JAVASE提供了满足各种需求的API,在使用这些API前,先了解其继承与接口操作架构,才能了解何时采 用哪个类,以及类之间如何彼此合作,从而达到灵活应用。
集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection 和双列集合
java.util.Map ,今天我们主要学习Collection 集合
从上面的描述可以看出JDK中提供了丰富的集合类库,为了便于初学者进行系统地学习,接下来通过一张图来描述整个集合类的继承体系。
其中,橙色框里填写的都是接口类型,而蓝色框里填写的都是具体的实现类。这几天将针对图中所列举 的集合类进行逐一地讲解。
集合本身是一个工具,它存放在java.util包中。在Collection 接口定义着单列集合框架中最最共性的内容。
1.3Collection 常用功能
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法, 这些方法可用于操作所有的单列集合。方法如下:
public boolean add(E e) : 把给定的对象添加到当前集合中 。
:清空集合中所有的元素。
public boolean remove(E e) : 把给定的对象在当前集合中删除。public boolean contains(E e) : 判断当前集合中是否包含给定的对象。public boolean isEmpty() : 判断当前集合是否为空。
public int size() : 返回集合中元素的个数。
public Object[] toArray() : 把集合中的元素,存储到数组中。
方法演示:
tips: 有关Collection中的方法可不止上面这些,其他方法可以自行查看API学习。
二、泛型
3.1泛型概述
在前面学习集合时,我们都知道集合中是可以存放任意对象的,利用Object的引用能够参数任意化,但需要进行强制转换,这种情况在程序运行时才回出现,是一个安全隐患。本次课讨论Java中提供泛型机制来解决这种类型安全隐患的问题。
大家观察下面代码:
程序在运行时发生了问题java.lang.ClassCastException。为什么会发生类型转换异常呢?
我们来分析下:由于集合中什么类型的元素都可以存储。导致取出时强转引发运行时
ClassCastException。怎么来解决这个问题呢?
Collection虽然可以存储各种对象,但实际上通常Collection只存储同一类型对象。例如都是存储字符串 对象。因此在JDK5之后,新增了泛型(Generic)语法,让你在设计API时可以指定类或方法支持泛型,这样我们使用API的时候也变得更为简洁,并得到了编译时期的语法检查。
泛型:可以在类或方法中预支地使用未知的类型。
tips:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object
类型。
3.2使用泛型作用和应用
概念:泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
3.3泛型的定义与使用
我们在集合中会大量使用到泛型,这里来完整地学习泛型知识。
泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
定义和使用含有泛型的类
定义格式:
例如,API中的ArrayList集合:
使用泛型: 即什么时候确定泛型。
在创建对象的时候确定泛型
例如, ArrayList<String> list = new ArrayList<String>();
此时,变量E的值就是String类型,那么我们的类型就可以理解为:
再例如, ArrayList<Integer> list = new ArrayList<Integer>();
此时,变量E的值就是Integer类型,那么我们的类型就可以理解为:
举例自定义泛型类
使用:
含有泛型的方法
定义格式:
例如,
使用格式:调用方法时,确定泛型的类型
含有泛型的接口
定义格式:
例如,
使用格式:
1、定义类时确定泛型的类型
例如
此时,泛型E的值就是String类型。
2、始终不确定泛型的类型,直到创建对象时,确定泛型的类型
例如
确定泛型:
3.4泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符基本使用
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接受数据,不能往该集合中存储数据。
举个例子大家理解使用即可:
tips:泛型不存在继承关系 Collection list = new ArrayList();这种是错误的。
通配符高级使用 受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
格式: 意义:
泛型的下限:
格式: 意义:
比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类