引入:
虽然集合可以存储任意对象,但是如果需要使用对象的特有方法,那么就需要类型转换。
由于集合中存入的是特定的对象,取出的时候是Object对象,需要强制类型转换,可能诱发类型转换异常,而且在编译时期无法发现问题。——使用泛型可解决这种问题
泛型是jdk1.5使用的新特性
泛型的好处在于:
1. 将运行时的异常提前至了编译时
2. 避免了无谓的强制类型转换
泛型在集合中的常见应用
有以下三种写法:
ArrayList<String> list = new ArrayList<String>();ArrayList<String> list = new ArrayList();
ArrayList list = new ArrayList<String>();
推荐使用第一种
方法上自定义泛型
格式:
修饰符 <声明自定义的泛型>返回值类型 函数名(使用自定义泛型 ...)
例:定义一个方法可以接收任意类型的参数,而且返回值类型必须要与实参的类型一致。
public static <T>T getData(T t)
public static <T>void print(T[] t)
方法泛型注意的事项:
1. 在方法上自定义泛型,这个自定义泛型的具体数据类型是在调用该方法的时候传入实参时确定具体的数据类型的
2. 自定义泛型只要符合标识符的命名规则即可, 但是自定义泛型我们一般都习惯使用一个大写字母表示
泛型类
泛型类的定义格式:
class 类名 <声明自定义泛型> {
}
泛型类要注意的事项
1. 在类上自定义泛型的具体数据类型是在使用该类的时候创建对象时候确定的;
2. 如果一个类在类上已经声明了自定义泛型,如果使用该类创建对象的时候没有指定泛型的具体数据类型,那么默认为Object类型;
3.在类上自定义泛型不能作用于静态的方法,如果静态的方法需要使用自定义泛型,那么需要在方法上自己声明使用。
泛型接口
泛型接口的定义格式:
interface 接口名 <声明自定义泛型> {
}
泛型接口要注意的事项:
1. 接口上自定义的泛型的具体数据类型是在实现一个接口的时候指定的;
2. 在接口上自定义的泛型如果在实现接口的时候没有指定具体的数据类型,默认为Object类型;
3.实现一个接口的时候,还不明确目前要操作的数据类型,则等待创建接口实现类对象的时候指定泛型的具体数据类型;
泛型的上下限
? super——存储某类的父类元素——下限
? extends——存储某类的子类元素——上限
例如:
定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Integer或者是Integer的父类类型数据。
public static void getData(Collection<? super Integer> c)
定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Number或者是Number的子类类型数据
public static void getData(Collection<? extends Number> c)
补充注意点
在泛型中不能使用基本数据类型,如果需要使用基本数据类型,那么就使用基本数据类型对应的包装类型。
byte----> Byte
short----> Short
int----> Integer
long----> Long
double ----> Double
float ----> Float
boolean---->Boolean
char----> Character