1 泛型入门
集合元素过去默认为Object类型,无法指定元素类型,编译时不检查类型,而且每次取出对象都要进行强制类型转换,泛型出现避免了这种臃肿的代码。下列代码会看到编译时不检查元素类型导致的异常。
public class ListErr {
public static void main(String[] args) {
List strList = new ArrayList();
strList.add("人有悲欢离合");
strList.add("月有阴晴圆缺");
strList.add(23333);
//ClassCastException
strList.forEach(str -> System.out.println(((String) str).length()));
}
}泛型用于指定集合存储数据的类型。
List<String> books=new ArrayList<String>();
上述代码定义集合时使用泛型,创建对象时构造器也给出泛型类型,这样显然是多余的。java7做了改进。
List<String> books=new ArrayList<>();
2 深入泛型
- 2.1定义泛型接口、类
我们可以在定义一个类时允许它使用泛型,通过阅读java提供的集合接口源码可以知道如何定义泛型接口。
//定义接口时指定了一个类型形参E
public interface List<E> extends Collection<E> {
//在接口中将形参E作为类型使用
boolean add(E e);
Iterator<E> itorator;
// ...
}在实际使用时,只需要在声明对象时传入E的实参即可 。
- 2.2 从泛型类派生子类
从泛型类派生子类时,我们可以为泛型指定实参,也可以不使用,注意不要再使用形参T。
public class Apple<T> {
private T info;
public T getInfo(){
return this.info;
}
}
public class SmallApple extends Apple<String> {
private String info;
public String getInfo() {
return this.info;
}
}2.3 并不存在泛型类
实际上,泛型只是设计来用于方便编程,并不会由于指定类型不同而生成不同的class文件。
public class GenericTest {
public static void main(String[] args) { List<String> strList = new ArrayList<>(); List<Integer> intList = new ArrayList<>(); // true System.out.println(strList.getClass() == intList.getClass()); }}
也就是说,不管传入实参是不是一个类型,它们仍然被当成一个类型的数据,不允许在静态成员中使用泛型形参。

京公网安备 11010502036488号