本篇主要讲解java泛型的理解、集合中简单使用泛型、自定义泛型结构(包括类、接口、方法)。
通俗来讲,可以把泛型理解为带有标签的罐子,罐子贴着红糖的标签,就只能放红糖;罐子贴着白糖的标签,就只能放白糖,不可以乱放。用集合来解释,可以理解为:
list贴上了String的泛型标签,就只能添加String类型的数据;list1贴上了Integer的泛型标签,就只能添加Integer类型的数据;否则就会报错。
List
,这表明该List只能保存字符串类型的对象。- public interface List<E> extends Collection<E> {
- Iterator<E> iterator();
- <T> T[] toArray(T[] a);
- boolean add(E e);
-
所以为什么要有泛型呢?直接用Object类型存储数据不香吗?
以集合为例,当我们不使用泛型时:
- public void test1() {
- List<Object> list = new ArrayList<>();
- list.add(123);
- list.add(456);
- list.add("789");
- for (Object o : list) {
- Integer item = (Integer) o;
- System.out.println(item);
- }
- }
-
运行结果:
当我们使用泛型时:
- public void test2() {
- List<Integer> list = new ArrayList<>();
- list.add(123);
- list.add(456);
- // list.add("789");添加失败
- for (Integer integer : list) {
- System.out.println(integer);
- }
- }
我们可以发现,使用泛型后,当添加的数据类型不满足条件时,编译就会报错;在遍历集合时,还可以避免强制类型转换。
- public class Order<T> {
- String orderName;
- int orderId;
- //类的内部结构就可以使用类的泛型
- T orderT;
- //构造器
- public Order(){
- //泛型数组
- T[] arr = (T[]) new Object[8];
- }
- public Order(String orderName,int orderId,T orderT){
- this.orderName = orderName;
- this.orderId = orderId;
- this.orderT = orderT;
- }
- //注意,下面的三个方法都不是泛型方法
- public T getOrderT(){
- return orderT;
- }
- public void setOrderT(T orderT){
- this.orderT = orderT;
- }
- @Override
- public String toString() {
- return "Order{" +
- "orderName='" + orderName + '\'' +
- ", orderId=" + orderId +
- ", orderT=" + orderT +
- '}';
- }
- }
-
需要注意的是:
异常类不能声明为泛型:
编译不通过:
静态方法中不能使用泛型:
因为是静态方法,即可以使用类来调用;当使用类来调用方法时,并不知道参数T指的是什么,所以不行。当使用对象调用方法时,通过构造器创建对象时,就已经指明了T是什么类型。 由于类和接口没有很大的区别,所以为了文章的完整性,就继续以类来讲解泛型相关的知识:
- class Father
, T2> { - }
- // 子类不保留父类的泛型
- // 1)没有类型 擦除
- class Son1 extends Father {// 等价于class Son extends Father
- }
- // 2)具体类型
- class Son2 extends Father
, String> { - }
- // 子类保留父类的泛型
- // 1)全部保留
- class Son3
, T2> extends Father, T2> { - }
- // 2)部分保留
- class Son4
extends Father, T2> { - }
-
- class Father
, T2> { - }
- // 子类不保留父类的泛型
- // 1)没有类型 擦除
- class Son, B> extends Father{//等价于class Son extends Father
- }
- // 2)具体类型
- class Son2, B> extends Father
, String> { - }
- // 子类保留父类的泛型
- // 1)全部保留
- class Son3
, T2, A, B> extends Father, T2> { - }
- // 2)部分保留
- class Son4
, A, B> extends Father, T2> { - }
-
总结:
[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
- //这些都是泛型方法:
- public <E> void say(List<E> list) { }
-
- public static <E> List<E> copyFromArrayToList(E[] arr) {
- ArrayList<E> list = new ArrayList<>();
- for (E e : arr)
- list.add(e);
- return list;
- }