1. 泛型概述

    1. 泛型: 是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
    2. 泛型的格式:<数据类型>
    3. 注意:泛型只能支持引用数据类型
  2. 泛型的好处:

    1. 统一数据类型
    2. 把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来。
    3. 扩展知识点:Java中的泛型是伪泛型
  3. 泛型的细节

    1. 泛型中不能写基本数据类型
      1. 因为基本数据类型在集合中没有办法转换为Object类 只有写包装类才能转成Object
    2. 指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类类型
      1. 但大多数是要求 传入类型与泛型类型一致
    3. 如果不写泛型,类型默认Object
  4. 泛型可以在很多地方可以定义

    1. 泛型方法 代码示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import java.util.ArrayList;

    public class ListUtil {
    private ListUtil(){};

    // 类中定义一个静态方法addAll 用来添加多个集合的元素

    // E也可以加在类后面

    /**
    * 参数1: 集合
    * 参数2: 最后要添加的元素
    * @param <E>
    */
    public static <E> void addAll(ArrayList<E> list,E e1,E e2,E e3){
    list.add(e1);
    list.add(e2);
    list.add(e3);
    }

    // E..e 可变参数
    public static <E> void addAll(ArrayList<E> list,E...e){
    for(E element : e){
    list.add(element);
    }
    }
    }

    测试方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import java.util.ArrayList;

    /**
    * 定义一个工具类: ListUtil
    * 类中定义一个静态方法addAll 用来添加多个集合的元素
    *
    */
    public class GenericsDemo1 {
    public static void main(String[] args) {
    ArrayList<String> list1 = new ArrayList<>();
    ListUtil.addAll(list1,"aaa","bbb","ccc");

    System.out.println(list1);

    ArrayList<Integer> list2 = new ArrayList<>();
    ListUtil.addAll(list2,1,2,3);
    System.out.println(list2);
    }
    }
    1. 泛型接口
  5. 泛型的继承和通配符

    1. 泛型不具备继承性 但是数据具备继承性

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import java.time.ZonedDateTime;
import java.util.ArrayList;

public class GenericsDemo3 {
public static void main(String[] args) {
/**
* 泛型不具备继承性 但是数据具备继承性
*/
// 创建集合的对象
method(new ArrayList<Ye>());

// 下面两条会报错 泛型不具备继承性
//method(new ArrayList<Fu>());
//method(new ArrayList<Zi>())


method3(new ArrayList<Fu>());
method3(new ArrayList<Zi>());
// 下面会报错 因为Student并不继承Ye
// method3(new ArrayList<Student>());

method4(new ArrayList<Fu>());
// 下面会报错 Zi并非Fu的父类
//method4(new ArrayList<Zi>());
}

public static void method(ArrayList<Ye> list){

}

/**
*
* 此时泛型里面写的是什么类型 那么就只能传递什么类型的数据 (method2)
* 弊端:
* 利用泛型方法有一个 此时他可以接受任意的数据类型 (Ye Fu Zi Student)
* 希望:
* 本方法虽然不确定类型 但是以后希望只能传递(Ye Fu Zi)
*
* 此时我们就可以使用泛型的通配符: (method3)
* ? 也表示不确定的类型
* 他可以进行类型的限定
* ? extends E: 表示可以传递E或者E所有的子类类型
* ? super E: 表示可以传递E或者E所有的父类类型
*
* 应用场景:
* 1. 如果我们在定义类、方法、接口的时候,如果类型不确定,就可以泛型类、泛型方法、泛型接口
* 2. 如果类型不确定,但是能知道以后只能传递某个继承体系中 就可以使用泛型的通配符
*
* 泛型的通配符:
* 关键点: 可以限定类型的范围
*
*
*/
public static <E> void method2(ArrayList<E> list){

}

// 可以传递任意类型但一定要是 Ye 或是 Ye的子类
public static void method3(ArrayList<? extends Ye> list){

}

// 可以传递任意类型 但一定要是 Fu 或者是 Fu的父类
public static void method4(ArrayList<? super Fu> list){
}
}

class Ye{

}

class Fu extends Ye{

}

class Zi extends Fu{

}

class Student{

}

  1. 笔记总结