龗孖 龗孖
首页
  • JAVA
  • 设计模式
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 页面

    • HTML
    • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

靇孖

某微型企业非牛逼技术专家。
首页
  • JAVA
  • 设计模式
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 页面

    • HTML
    • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JAVA

    • JAVA基础

      • Java17新特性
      • JAVA面试题-常用框架
      • JAVA面试题-线程
      • JAVA面试题-集合
      • JAVA面试题-基础
      • 通俗易懂的理解JAVA泛型
      • Spring

    • MQ

    • 工具

    • 微服务

    • 数据库

    • 其他

    • 程序设计

    • 算法

    • 服务端
    • JAVA
    • JAVA基础
    龗孖
    2024-01-23
    目录

    通俗易懂的理解JAVA泛型

    泛型是JAVA 1.5版本之后引入的一个新特性,它允许在定义类、接口和方法的时候使用类型参数,这些类型参数将在使用时确定。泛型的引入,使得JAVA具有了更好的代码复用性,更好的类型安全性,更好的可读性。泛型的引入,使得JAVA具有了更好的代码复用性,更好的类型安全性,更好的可读性。

    JAVA泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

    # JAVA泛型的好处:

    1. 代码复用性:泛型类、泛型接口、泛型方法的代码可以被重用,不用重复编写相同的代码。
    2. 类型安全:泛型可以在编译时期进行类型检查,保证类型安全。
    3. 可读性:泛型可以减少强制类型转换的代码,提高代码的可读性。

    # 以动物界为例解释多态和泛型

    # 什么是多态

    多态就是同一种事物的多种形态,比如动物,狗,鸟,他们都是动物,但是他们的运动方式不同,这就是多态 不同的动物的运动方式不同,比如狗的运动方式是跑,鸟的运动方式是飞,那么我们可以定义一个动物类,然后定义一个狗类和鸟类,他们同属于动物,却又有不同的运动方法,这就实现了多态

    # 什么是泛型

    虽然同属于动物界,但是动物们的繁衍行为生下的后代也不相同 ,比如狗生下的后代是狗,鸟生下的后代是鸟 ,如果我们用一个类来表示动物,且定义一个繁衍行为返回后代

            public class Animal {
                public Animal breed(){
                    return new Animal();
                }
            }
    
    1
    2
    3
    4
    5

    如果我希望对某个具体的动物进行描述,就只能继承动物类,然后重写breed方法,比如狗类

            public class Dog extends Animal{
                @Override
                public Dog breed(){
                    return new Dog();
                }
            }
    
    1
    2
    3
    4
    5
    6

    那有没有一种方式 可以在我指定的动物是狗的时候 直接生出一只狗狗呢?这就需要用到泛型了

    我们可以定义一个占位符 T ,然后在breed方法中返回一个T类型的对象

            public class Animal<T> {
                public T breed(){
                    return new T();
                }
            }
    
    1
    2
    3
    4
    5

    使用的时候 只需要替换T为Dog 就可以了,这样当我需要获取狗的后代的时候,我就可以这样写

            Animal<Dog> dog = new Animal<>();
            Dog dog1 = dog.breed();
    
    1
    2

    这个T 可以是任何类型,比如狗,鸟,猫, 此时Animal<T> 就是一个泛型类,可以用来描述任何动物,而不用每次都去继承一个动物类,然后重写breed方法,这样就可以大大的减少代码量,提高代码的复用性

    # 类型安全

    如果说现在很多园区,每个园区都需要放入对应的动物,狮子区不能放入兔子,不然狮子就会吃掉兔子,那么我们就可以定义一个园区类,然后定义一个放入动物的方法,这个方法的参数就是一个泛型类

            public class Zoo<T extends Animal> {
                public void put(T animal){
                    System.out.println("放入了一个"+animal.getClass().getSimpleName());
                }
            }
    
    
    1
    2
    3
    4
    5
    6

    这样就可以保证放入的动物是对应的,这样就可以保证类型安全

    放入兔子

            Zoo<Rabbit> rabbitZoo = new Zoo<>();
            rabbitZoo.put(new Rabbit());
    
    1
    2

    放入狮子

            Zoo<Lion> lionZoo = new Zoo<>();
            lionZoo.put(new Lion());
    
    1
    2

    如果放入了一个错误对象,比如放入了一只狗,编译器就会报错

            Zoo<Lion> lionZoo = new Zoo<>();
            lionZoo.put(new Dog());
    
    1
    2

    # 泛型的使用细节

    类型实参不能是基本数据类型,比如int,boolean,但是可以是他们的包装类,比如Integer,Boolean

            Zoo<Integer> integerZoo = new Zoo<>();
            integerZoo.put(new Integer(1));
    
    1
    2

    静态方法不能使用泛型类中定义的泛型,因为静态方法优先于对象存在,所以静态方法中不能使用类中定义的泛型

            public class Zoo<T extends Animal> {
                public static void put(T animal){  //这里会出现错误,因为静态方法不能使用泛型类中定义的泛型
                   
                    System.out.println("放入了一个"+animal.getClass().getSimpleName());
                }
            }
    
    1
    2
    3
    4
    5
    6

    修饰符与返回值类型中间的 泛型标识符 <T,E,…>,是 泛型方法的标志

    吧v

            public class Zoo<T extends Animal> {
                public void put(T animal){
                    System.out.println("放入了一个"+animal.getClass().getSimpleName());
                }
                public <T> void put2(T animal){  //这里的T和泛型类中的T没有任何关系,这里的T是一个新的类型,也可以写成B ,C ,D等等 但是需要再修饰符后面声明
                    System.out.println("放入了一个"+animal.getClass().getSimpleName());
                }
                public <T,B,C,D,E> void put2(T animal,B b,C c,D d){  //这里的T和泛型类中的T没有任何关系,这里的T是一个新的类型,也可以写成B ,C ,D等等 但是需要再修饰符后面声明
                     //....
                }
            }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 泛型中的extends 和 super

    extends 表示上界,只能是指定类型或者指定类型的子类 super 表示下界,只能是指定类型或者指定类型的父类

            public class Zoo<T extends Animal> {
                public void put(T animal){
                    System.out.println("放入了一个"+animal.getClass().getSimpleName());
                }
            }
    
    1
    2
    3
    4
    5

    这里的T 只能是Animal或者Animal的子类,如果我想要放入Animal的父类,比如Object,就需要使用super

            public class Zoo<T super Animal> {
                public void put(T animal){
                    System.out.println("放入了一个"+animal.getClass().getSimpleName());
                }
            }
    
    1
    2
    3
    4
    5

    这里的T 只能是Animal或者Animal的父类,如果我想要放入Animal的子类,比如Dog,就需要使用extends

    上次更新: 2024/11/01, 16:22:32
    JAVA面试题-基础
    SpringBoot3项目快速构建

    ← JAVA面试题-基础 SpringBoot3项目快速构建→

    最近更新
    01
    树中两个节点的最低公共祖先
    10-17
    02
    hexo多平台多博客网站同步
    09-04
    03
    最长不含重复字符的子字符串
    09-03
    更多文章>
    Theme by Vdoing | Copyright © 2015-2024 Ling ma | 996.icu | 京ICP备16011424号-1
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式