• 【檀越剑指大厂--泛型】泛型总结


    一.概念

    1.什么是泛型

    • 泛型的本质是类型参数化。
    • 允许在定义类、接口、方法时使用类型形参,当使用时指定具体类型。
    • 所有使用该泛型参数的地方都被统一化,保证类型一致。
    • 如果未指定具体类型,默认是Object类型。
    • 集合体系中的所有类都增加了泛型,泛型也主要用在集合。

    泛型是将类型参数化,允许定义在类、接口、方法时使用类型参数,当使用的时候指定具体类型。

    泛型主要应用在集合

    2.泛型的优点

    • 代码需要更精简
    • 程序更加健壮
    • 编码期,可读性很高

    3.泛型的上下限

    上限
    格式:类型名称 对象名称
    说明:只能接收该类型及其子类

    下限
    格式:类型名称 对象名称
    说明:只能接收该类型及其父类型

    4.类型擦除和桥接方法

    泛型是给javac编译器使用,在编译器编译之后的class文件中是没有泛型信息的,所以泛型的使用不会让程序运行效率收到影响,这个过程称之为擦除。
    由于类型擦除了,为了维持多态性,需要一些桥接方法类保持多态性,桥接方法是编译器自动生成的

    // 最初的代码
    public class Node<T> {
    	public T data;
    	public void setData(T data) {
    		this.data = data;
    	}
    }
    public class MyNode extends Node<Integer> {
    	public void setData(Integer data) {
    		//....
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    // jvm不认识泛型的,把泛型擦除掉, 兼容⽼版本jdk
    public class Node {
      public Object data;
      public void setData(Object data) {
        this.data = data;
      }
    }
    public class MyNode extends Node {
      // 桥接⽅法,编译器⾃动⽣成
      public void setData(Object data) {
        setData((Integer)data)
      }
      public void setData(Integer data) {
        //....
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二.使用

    1.通配符的上限

    /**
     * 测试类
     * 通配符的上限 List
     * 格式:类型名称 对象名称
     * 意义:只能接收该类型及其子类
     *
     * @author : kwan
     * @version : 1.0.0
     * @date : 2022/8/11 16:57
     */
    public class Collection_02_extends_super {
        public static void main(String[] args) {
            List<Dog> dogs = new ArrayList<>();
            dogs.add(new Dog());
    
            // 编译器只知道animals里保存的是Animal的子类
            //但是并不知道是哪个子类
            //Animal 是接口 ,无法添加
            List<? extends Animal> animals = dogs;
    
    //        animals.add(new Dog()); // 编译不通过
    //        animals.add(new Animal()); // 编译不通过
    //
            Animal animal = animals.get(0);
    //        Dog dog = animals.get(0); // 编译不通过
        }
    }
    
    • 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

    2.通配符的下限

    /**
     * 测试类
     * 通配符的下限 List
     * 格式:类型名称 对象名称
     * 意义:只能接收该类型及其父类
     *
     * @author : kwan
     * @version : 1.0.0
     * @date : 2022/8/11 16:57
     */
    public class Collection_03_extends_super {
      public static void main(String[] args) {
        List<Dog> as = new ArrayList<>();
        as.add(new Dog());
        // 编译器只知道bs里保存的是BigDog的父类
        List<? super BigDog> bs = as;
        //      bs.add(new Dog()); // 编译不通过
        bs.add(new BigDog());
        //      Dog a = bs.get(0); // 编译不通过
        //      BigDog b = bs.get(0); // 编译不通过
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    Java常用集合解析
    【LeetCode】Day177-统计一致字符串的数目
    Linux中使用nvidia-smi命令实时查看指定GPU使用情况
    企业安全不求人,一个小技巧就能搞定
    编写一个GStreamer插件
    Fedora Linux上使用Homebrew包管理器dnf异同
    MySQL 根据【父ID】获取【所有子节点】
    react:handleEdit={() => handleEdit(user)} 和 handleEdit={handleEdit(user)}有啥区别
    flink集群与资源@k8s源码分析-集群
    Avalonia开发(二)项目结构解析
  • 原文地址:https://blog.csdn.net/qyj19920704/article/details/126319073