一、泛型特点

1、泛型提供了编译时类型安全检测机制,在编译时能检测到非法的类型。
2、集合如果没有指定泛型,就会默认为Object类型,为了避免遍历的时候出现类型转换异常,需要先判断类型,所以这样很麻烦。
3、有了泛型后,就实现设置了集合所存的数据类型,遍历集合时就不需要进行类型转换就可以直接遍历了。
4、泛型只能是引用类型,不能是基本数据类型,如int、double是不行的。

eg:

List<String> list = new ArrayList<String>();

二、泛型类

泛型类:

public class Student<T> {
    private T stuNumber;

    public T getStuNumber() {
        return stuNumber;
    }

    public void setStuNumber(T stuNumber) {
        this.stuNumber = stuNumber;
    }
}

调用:

public class Test01 {
    public static void main(String[] args) {
        Student<String> student1 = new Student<String>();
        student1.setStuNumber("10001");
        System.out.println(student1.getStuNumber());
        System.out.println("-----------------------");
        Student<Integer> student2 = new Student<Integer>();
        student2.setStuNumber(1);
        System.out.println(student2.getStuNumber());
    }
}

三、泛型方法

泛型方法:

public class Test02Domin {
    public <T> void show(T t){
        System.out.println(t);
    }
}

调用:

public class Test02 {
    public static void main(String[] args) {
        Test02Domin test02Domin = new Test02Domin();
        test02Domin.show("字符串类型");
        test02Domin.show(111);
        test02Domin.show(11.11);
        test02Domin.show(false);
    }
}

四、泛型接口

泛型接口:

public interface QizeInterface<T> {
    T show(T t);
}

实现类:

public class QizeInterfaceImpl<T> implements QizeInterface<T>{
    @Override
    public T show(T t){
        return t;
    }
}

调用:

public class Test03 {
    public static void main(String[] args) {
        QizeInterfaceImpl<String> qize1 = new QizeInterfaceImpl<String>();
        System.out.println(qize1.show("我是字符串"));
        QizeInterfaceImpl<Integer> qize2 = new QizeInterfaceImpl<Integer>();
        System.out.println(qize2.show(11));
        QizeInterfaceImpl<Boolean> qize3 = new QizeInterfaceImpl<Boolean>();
        System.out.println( qize3.show(false));
    }
}

五、泛型接口与泛型方法融合使用

泛型接口、方向方法:

public interface QizeInterface<T> {
    <M> T show(T t, M m);
}

实现类:

public class QizeInterfaceImpl<T> implements QizeInterface<T>{
    @Override
    public <M> T show(T t, M m) {
        System.out.println(m);
        return t;
    }
}

调用:

public class Test03 {
    public static void main(String[] args) {
        QizeInterfaceImpl<String> qize1 = new QizeInterfaceImpl<String>();
        System.out.println(qize1.show("我是字符串","ces"));
        QizeInterfaceImpl<Integer> qize2 = new QizeInterfaceImpl<Integer>();
        System.out.println(qize2.show(11,22));
        QizeInterfaceImpl<Boolean> qize3 = new QizeInterfaceImpl<Boolean>();
        System.out.println( qize3.show(false,true));
    }
}

六、泛型通配符

  1. 概述

泛型通配符能够用于接收,表示可以接收所有的泛型类型;
泛型通配符不能用于添加。

eg:

public class Test01 {
    public static void printList(List<?> list){
        Iterator<?> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    
    public static void main(String[] args) {
        ArrayList<String> arrayListString = new ArrayList<>();
        for (int i=0;i<5;i++){
            arrayListString.add("i:"+i);
        }
        printList(arrayListString);
        System.out.println("-------------------");
        ArrayList<Integer> arrayListInteger = new ArrayList<>();
        for (int i=0;i<5;i++){
            arrayListInteger.add(i);
        }
        printList(arrayListInteger);
    }
}
  1. 泛型通配符的上限

表示可以接收某类和其所有子类:
eg:
父类:

public class QizeParent {
}

子类:

public class Student extends QizeParent{
}
public class Test02 {
    /**
     * 泛型通配符上限
     * List<? extends QizeParent> 上限
     * 表示可以接收 QizeParent类和其所有子类
     * @param list
     */
    public static void printList(List<? extends QizeParent> list){

    }

    public static void main(String[] args) {
        List<QizeParent> qizeParents = new ArrayList<>();
        ArrayList<Student> students = new ArrayList<>();
        printList(qizeParents);
        printList(students);
    }
}
  1. 泛型通配符的下限

表示可以接收某类和其所有父类:
eg:
父类:

public class QizeParent {
}

子类:

public class Student extends QizeParent{
}
public class Test02 {
    /**
     * 泛型通配符下限
     * List<? super Student> 下限
     * 表示可以接收 Student类和其所有父类
     * @param list
     */
    public static void printList(List<? super Student> list){

    }

    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        List<QizeParent> qizeParents = new ArrayList<>();
        printList(students);
        printList(qizeParents);
    }
}
  1. 可变参数(与泛型无关)
    如int … a 为可变参数,底层是基于数组来实现的,表示传递的参数可变,底层封装成数组的形式传递给方法。
    如果除了可变参数外还有其他的参数,则需要把可变参数放后面。
public class Test03 {
    public static void main(String[] args) {
        System.out.println("sum:"+sum(1,1));
        System.out.println("sum:"+sum(2,2,2));
        System.out.println("sum:"+sum(3,3,3,3));
        System.out.println("sum:"+sum(4,4,4,4,4));
    }

    /**
     * int ... a  为可变参数,底层是基于数组来实现的
     * 表示传递的参数可变,底层封装成数组的形式传递给方法
     * 如果除了可变参数外还有其他的参数,则需要把可变参数放后面
     * @param c
     * @param a
     * @return
     */
    public static int sum(int c, int ... a){
        int sum = 0;
        for (int i=0; i< a.length; i++){
            sum += a[i];
        }
        return sum;
    }
}
  1. 泛型的擦除机制

泛型原理底层会使用擦除机制,泛型是在编译阶段限制传递的类型,在编译后会擦除泛型。
将一个List集合 泛型 赋值给一个没有使用到泛型的list集合,直接去除泛型,这就是擦除机制。

public static void main(String[] args) {
	List<String> strings = new ArrayList<>();
    strings.add("qize");
    //strings.add(1); //报错
    //将一个List集合  泛型 赋值给一个没有使用到泛型的list集合,直接去除泛型
    List list = strings;
    list.add(1);
}