一,泛型数组列表
ArrayList是一个有类型参数的泛型类,为了指定数组列表保存的元素对象的类型,需要用一对尖括号将类名括起来追加到ArrayList后面。
冷知识
1,如果可以知道或能够估计出数组可能存储的元素数量,就可以在填充数组之前调用ensureCapacity方法:
例:staff.ensureCapacity(100);
另外还可以把初始容量传递给ArrayList构造器。
例:ArrayList staff = new ArrayList<>(100);
2,一旦能够确认数组列表的大小将保持恒定,不再发生变化,就可以调用trimToSize方法。这个方法将存储块的大小调整为保存当前元素数量所需要的存储空间。
二,泛型程序设计
为什么要使用泛型程序设计?
泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。
在集合中存储对象并在使用前进行类型转换非常不方便,泛型防止了那种情况的发生。它提供了编译期的类型安全,确保你只能把正确类型的对象放入集合中,避免了在运行时出现ClassCastException。
1,泛型类
泛型类就是有一个或多个类型变量的类
常用的泛型标识:T、E、K、V
public class Pair<T,泛型标识,泛型标识……>
{
private T first;
private T second;
public Pair(){first = null; second = null;}
public Pair(T first , T second){this.first = first; this.second = second;}
1,泛型类在创建对象的时候,没有指定类型,将按照object类型来操作
2,泛型类不支持基本数据类型
3,同一泛型类,根据不同的数据类型创建的对象,本质上是同一类型。
4,从泛型类派生子类:
子类也是泛型类,子类和父类的泛型类型要保持一致。
子类不是泛型类,父类要明确泛型的数据类型。
2,泛型方法
泛型方法是在调用方法的时候指明泛型的具体类型。 泛型方法可以在普通类中定义,也可以在泛型类中定义。
泛型方法可以定义为静态,方便调用。
泛型方法的参数可变。
修饰符<T,E,……>返回值类型 方法名(形参列表){
方法体……
}
public static <E> E getProduct(ArrayList<E> list){
return ……;
}
//可变参数
public static <E> void print(E... e){
for(int i = 0;i < e.length;i++)
System.out.println(e[i]);
}
3,泛型接口
泛型接口定义:
interface 接口名称<泛型标识、泛型标识>{
泛型标识 方法名();
……
}
泛型接口的使用:
实现类不是泛型类,接口要明确数据类型
实现类也是泛型类,实现类要和接口的泛型类型要一致
4,类型通配符
通配符存在的意义是允许类型参数发生变化。类型通配符一般是使用“?”代替具体的类型实参。所以类型通配符是类型实参,而不是类型形参。
类型通配符的上限
传递参数只能为实参或实参的子类,使用extends关键字。
public static void showBox(Box<? extends Number> box){
}
类型通配符的下限
要求该泛型的类型,只能是实参类型,或实参类型的父类类型,使用super关键字。
5,类型擦除
泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型有关的信息会被擦除掉,我们称之为–类型擦除。
无限制类型擦除:类型变量会被替换为object。
有限制类型擦除:类型变量会被替换成类型通配符的上界。