• Java之泛型


    泛型快速入门

    问题

    在这里插入图片描述

    泛型前代码

    没学泛型前的代码

    package com.hansp;
    
    import java.util.ArrayList;
    @SuppressWarnings({"all"})
    public class genericParadigm {
        public static void main(String[] args) {
    
            ArrayList arrayList = new ArrayList();
            arrayList.add(new Dog("sw",10));
            arrayList.add(new Dog("s",11));
            arrayList.add(new Dog("e",12));
            arrayList.add(new Dog("qe",13));
            arrayList.add(new Dog("we",14));
            System.out.println(arrayList);
        }
    }
    class Dog{
        public String name;
        public int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    • 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

    在这里插入图片描述

    这样写的话
    假如我们的程序员不小心添加了一只猫(与想添加的对象类型不同)

    如果你有遍历,并且向下转型成Dog想用Dog独特的方法
    此时就会发生类型转换异常
    而且
    你需要进行foreach遍历的时候

    for(Object o:arraylist){
    //操作
    //如果调用Dog类方法
    Dog a=(Dog)o;//需要向下转型,每个都向下转型效率会低
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里的Object还不能直接换成Dog尽管你存的可能都是Dog

    此时我们就可以用泛型解决前面的问题

    泛型后代码

    经历泛型后的改编版

    package com.hansp;
    
    import java.util.ArrayList;
    @SuppressWarnings({"all"})
    public class genericParadigm {
        public static void main(String[] args) {
            //当这样带上时,这个集合只能存放Dog类型
    
            ArrayList<Dog> arrayList = new ArrayList<Dog>();
            arrayList.add(new Dog("sw",10));
            arrayList.add(new Dog("s",11));
    
            for (Dog a:arrayList//这里可以直接取Dog效率比之前高
                 ) {
                System.out.println(a);
            }
        }
    }
    class Dog{
        public String name;
        public int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    • 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

    运行效果
    在这里插入图片描述
    试图在arrayList加入处理Dog外的其他对象
    细节在后面说
    在这里插入图片描述

    改进处

    改进了两点
    1.可以直接取Dog
    2.不可以存放处理你指定外的其他元素
    在这里插入图片描述

    泛型基本介绍

    可以把泛型理解为可以表示数据类型的一种数据类型
    在这里插入图片描述

    4的解释

    package com.hansp.generic;
    
    public class generic01 {
        public static void main(String[] args) {
    
            Person<Object> objectPerson = new Person<>();
            //如果你不写的话,默认为Object
            objectPerson.s=new String("c");
            Person<String> Person = new Person<String>();
        //现在Person里面的s只能是String了
        Person.s="小袁";//传入其他类型的会报错
        }
    }
    class Person<T>{
        String name;//代表我们的name是String类型
        T s;//s则是T类型,这个T类型是你在创建的时候定义的类型
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    就是相当于把你<>里面传入的类型(实参)
    代替为那个类里面的T(形参)
    如图
    在这里插入图片描述
    图中相当于把 E全换为Integer
    我们的是相当于把T全换为String

    所以说可以把泛型理解为可以表示数据类型的一种数据类型

    泛型的语法(应用实例)

    在这里插入图片描述

    题目

    在这里插入图片描述

    代码

    package com.hansp.generic;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    
    public class generic01 {
        public static void main(String[] args) {
            HashMap<String, Student> Map = new HashMap<String,Student>();
            Student a = new Student("A");
            Student b = new Student("B");
            Student c = new Student("C");
            Map.put(a.name,a);
            Map.put(b.name,b);
            Map.put(c.name,c);
            Collection<Student> values = Map.values();
    
            for (Student d:values
                 ) {
                System.out.println(d);
            }
            Iterator<Student> iterator = values.iterator();
            while (iterator.hasNext()) {
                Student next =  iterator.next();
                System.out.println(next);
            }
    
        }
    }
    class Student{
        String name;
    
        public Student(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    
    • 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

    泛型使用细节

    在这里插入图片描述

    1.泛型只能是引用数据类型
    2.

    class A extends B{}
    new ArrayList<B>();
    这个集合不仅可以存放B类型的对象还可以A类型(B的子类)的对象
    
    • 1
    • 2
    • 3

    3.接口<> 名字=new 接口继承类()<>;就是多态
    然后实际开发中用的较多的是

    List<String> a=new ArrayList<>();//没错就是把右边的那个<>里面的东西去掉 
    
    • 1

    在这里插入图片描述
    自动生成的也是省略的
    而且省略和不省略是一样的

    new ArrayList<Integer>().var
    ArrayList<Integer> a=new ArrayList<>();//上面代码生成的结果
    ArrayList<Integer> a=new ArrayList<>();等同于ArrayList<Integer> a=new ArrayList<Integer>();
    
    • 1
    • 2
    • 3

    在这里插入图片描述没有指定具体类型默认为Object

    自定义型泛型

    自定义泛型类

    在这里插入图片描述
    下面就是自定义泛型类的例子
    在这里插入图片描述
    1.R和M和T都是数据类型
    r和m和t都是属性
    可以在成员中使用
    比如说构造器
    在这里插入图片描述
    还可以在get和set方法里用
    在这里插入图片描述
    这个比较难想
    要了解对应大写字母的数据类型
    用set方法才能放入对应数据类型

    在这里插入图片描述
    因为类型没有确定,就不知道要开辟多大空间,所以不能初始化

    3.在这里插入图片描述
    静态方法是和类相关的,不是和对象相关,在类加载时,对象还没有创建
    静态方法或者属性使用泛型,JVM不能完成初始化(不知道具体类型,不知道怎么开辟空间)
    4和5在前面说过

    自定义泛型接口

    在这里插入图片描述
    1.注意接口中的属性都是静态性质的
    接口的属性的修饰符只能是public static final。比如int a = 1; 实际上是public static final int a = 1(必须初始化)

    左边是泛型接口的定义
    右边是继承泛型接口
    如果是第一种Class C implements IUsb{
    }
    等同于Class C implements IUsb{
    }
    在这里插入图片描述
    而且

    用快捷生成会自动把原来的大写字母替换成你写的数据类型
    继承接口
    Iusb{
    }
    在这里插入图片描述
    实现接口
    在这里插入图片描述
    都是这样

    3.在这里插入图片描述

    自定义泛型方法

    在这里插入图片描述
    1.
    在这里插入图片描述
    在这里插入图片描述
    2.
    在这里插入图片描述
    3.注意3
    方法使用泛型和泛型方法是不一样的
    泛型方法
    public void x(T t,R r){
    }
    使用泛型的方法
    public void e(M m){
    }
    这里是使用了类中声明的泛型

    泛型方法可以使用自己的泛型也可以使用类中声明的泛型
    比如
    public void x(T t,R r,M m){
    }
    M是类中的泛型
    T和R是泛型方法里的泛型

    泛型的继承和通配

    在这里插入图片描述

    1.不对
    不能这样写,前后必须对应,或者后面什么也不写
    234比较好理解
    属于是不仅约束
    你传入实现了List类型的类的对象
    还要规定你这个对象的泛型的范围
    是都可以
    还是要必须是哪个类型的子类或者父类
    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    Hamiton图系列文章 (2) Hamilton图道路矩阵类的乘法设计
    vue3中动态设置ref,如表格中使用级联选择器
    【JavaEE】实现简单博客系统-前端部分
    37.图练习(王道第6章综合练习)
    HTML5+CSS3+JS小实例:鼠标滚轮水平滚动
    【★★★★★ 第2章 线性表总结笔记 2022 9.12】
    oepncv c++ 连通组件扫描
    调教 文心一言 生成 AI绘画 提示词(Midjourney)
    7.3 服务端漏洞:密码找回逻辑漏洞检测和重现
    Hardhat开发智能合约和DApp
  • 原文地址:https://blog.csdn.net/y_k_j_c/article/details/126130647