java泛型以及泛型的使用

文章目录

    • 泛型
    • 泛型类的定义
    • 泛型类的使用
    • 类型擦除
    • 泛型类的使用-通配符
    • 通配符-上界
    • 通配符-下界
    • 泛型中的父子类型
    • 泛型方法
    • 泛型的限制

泛型

泛型类的定义

语法

class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}

类型形参一般使用一个大写字母表示,常用的名称有
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type

定义一个泛型类顺序表

public class MyArrayList<E> {
    private E[] array;
    private int size;
    public MyArrayList() {
// 泛型类型无法直接创建数组,具体的见下面的注意事项
        array = (E[])new Object[16];
        size = 0;
    }
    // 尾插
    public void add(E e) {
        array[size++] = e;
    }
    // 尾删
    public E remove() {
        E element = array[size - 1];
        array[size - 1] = null; // 将容器置空,保证对象被正确释放
        size--;
        return element;
    }
}

定义一个泛型类链表

public class MyLinkedList<E> {
    public static class Node<E> {
        private E value;
        private Node<E> next;

        private Node(E e) {
            value = e;
            next = null;
        }
    }

    private Node<E> head;
    private int size;

    public MyLinkedList() {
        head = null;
        size = 0;
    }

    // 头插
    public void pushFront(E e) {
        Node<E> node = new Node<>(e);
        node.next = head;
        head = node;
        size++;
    }
// 尾插

    public void pushBack(E e) {
        if (size == 0) {
            pushFront(e);
            return;
        }
        Node<E> cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = new Node<E>(e);
        size++;
    }
}

泛型类的使用

语法

泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
MyArrayList list = new MyArrayList();

类型擦除

class MyArrayList<E> {
// E 会被擦除为 Object
}
class MyArrayList<E extends Comparable<E>> {
// E 被擦除为 Comprable
}

类型擦除主要看其类型边界而定

编译器在类型擦除阶段在做什么?

  1. 将类型变量用擦除后的类型替换,即 Object 或者 Comparable
  2. 加入必要的类型转换语句
  3. 加入必要的 bridge method 保证多态的正确性

泛型类的使用-通配符

基本

? 用于在泛型的使用,即为通配符

通配符-上界

需要区分 泛型使用中的通配符上界 和 泛型定义中的类型上界

通配符-下界

泛型中的父子类型

public class MyArrayList { … }
// MyArrayList 不是 MyArrayList 的父类型
// MyArrayList 也不是 MyArrayList 的父类型
// 需要使用通配符来确定父子类型
// MyArrayList 是 MyArrayList 的父类型
// MyArrayList 是 MyArrayList 的父类型

泛型方法

定义语法

public class Util {
    public static <E> void swap(E[] array, int i, int j) {
        E t = array[i];
        array[i] = array[j];
        array[j] = t;
    }
}

方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { … }

泛型的限制

1. 泛型类型参数不支持基本数据类型
2. 无法实例化泛型类型的对象
3. 无法使用泛型类型声明静态的属性
4. 无法使用 instanceof 判断带类型参数的泛型类型
5. 无法创建泛型类数组
6. 无法 create、catch、throw 一个泛型类异常(异常不支持泛型)
7. 泛型类型不是形参一部分,无法重载

你可能感兴趣的:(java泛型以及泛型的使用)