1、泛型入门
让集合能记住其元素的数据类型,防止从集合取出对象时,强转类型容易引起ClassCastExeception异常
编译时不检查类型的异常
使用泛型
- List list = new ArrayList();
list.add(“123”);
list.add(123); //运行时会异常
List list = new ArrayList();
list.add(“123”);
list.add(123); //编译时会异常
Java7泛型的菱形语法
- List list = new ArrayList<>();
2、深入泛型
允许在定义接口、类时声明类型形参,类型形参在整个接口、类体内可当成类型使用
从泛型派生子类
- 当创建了带泛型声明的接口、父类之后,可以为该接口创建实现类,或从该父类派生子类,当使用这些接口、父类时不能再包含类型形参
- 定义方法时可以声明数据形参,调用方法时必须为这些数据形参传入实际的数据;而定义类、接口、方法时可以声明类型形参,使用类、接口、方法时应该为类型形参传入实际的类型
- 如果从Apple类派生子类,则在Apple类中所有使用T类型形参的地方都将被替换成String类型,重写父类的方法,就必须注意这一点
并不存在泛型类
- ArrayList类像一种特殊的ArrayList类,但实际上,系统并没有为ArrayList生成新的class文件,也不会把它当作新类来处理
- 不管泛型的实际类型参数是什么,它们在运行时总有同样的类,都会被当成同一个类处理,在内存中也只占用一块内存空间,因此在静态方法、静态初始化块活着静态变量的声明和初始化中不允许使用类型形参
- 由于系统中并不会真正生成泛型类,所以instanceof运算符后不能使用泛型类
3、类型通配符
允许Integer[]数组赋值给Number[]变量存在缺陷,因此在泛型设计时进行了改进,不再允许把List对象赋值给List变量
使用类型通配符
-
一个问号(?),将一个问号作为类型实参传给List集合
- public void test(List<?> c){
for(int i=0;i<c.size();i++){
System.out.println(c.get(i))
}
}
- public void test(List<?> c){
-
带通配符的List仅表示它是各种泛型List的父类,并不能把元素加入到其中
设定类型通配符的上限
- public class Canvas{
public void drawAll(List<? extends Sharp> sharps){
for(Shape s:shapes){
s.draw(this);
}
}
}
设定类型形参的上限
- 传给该类型形参的实际类型是上限类型或者上线类型的子类
- public class Apple{
T col;
}
4、泛型方法
定义泛型方法
- static void arrayToCollection(T[]a, Collection c){
for(T o:a){
c.add(o);
}
} - static void test(Collection<? extends T> from,Collection to){
for(T ele:from){
to.add(ele);
}
}
public static main(String[] args){
test(new ArrayList(),new ArrayList());
}
泛型方法和类型通配符的区别
-
大多数时候可以使用泛型方法来替代类型通配符
- public interface Collection{
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
}
public interface Collection{
boolean containsAll(Collection c);
boolean addAll(Collection c);
}
- public interface Collection{
-
如果没有形参之间的依赖关系或者方法返回值与参数之间的类型没有依赖关系,则不应该使用泛型
Java7的菱形语法与泛型构造器
通配符下限
- public static T copy(Collection<? super T> dest,Collection src){
T last = null;
for(T ele:src){
last = ele;
dest.add(ele);
}
return last;
}
泛型方法与方法重载
Java8改进的类型推断
5、擦除和转换
擦除:把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,所有在尖括号之间的类型信息都将被扔掉。List转成List,变成类型参数的上线,Object
6、泛型与数组
不支持泛型数组