java的泛型【详解】

news2025/1/18 6:57:19

定义类、接口、方法时,同时声明了一个或者多个类型变量(如:<E>) ,称为泛型类、泛型接口,泛型方法、它们统称为泛型。

作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。

1.泛型类:

        定义类的同时定义了泛型的类就是泛型类

        泛型类的格式:

        作用: 在编译阶段可以指定能操作的数据的类型

        原理: 把出现泛型变量的地方全部替换成传输的真实数据类型。

代码演示1:

package com.itheima.day06.teacher.c_generics;

import java.util.ArrayList;
/**
          集合用泛型的意义
             集合是存储对象的容器。一般来说存储的同种类型的对象。

             泛型:
                未知的类型     定义的时候不知道具体的类型。

             定义集合的时候,是不知道具体的集合对象存储什么类型对象的。
             所以集合采用泛型 来表示 未知的类型。
              你可以将泛型理解成一个占位符。

            使用集合的时候就需要确定 集合存储什么具体的类型了。

            确定之后  所有用到泛型的位置都会变成 具体的类型

     泛型 在定义不确定,在使用的时候必须确定。
        */
public class GenericsDemo01 {

    public static void main(String[] args) {
    
        //这里是没用泛型一个类型定义一个集合
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
       // list.add(12); //泛型限定传输的类型

        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(12);

        ArrayList list3 = new ArrayList();
        // Object
        list3.add("aaa");
        list3.add(123);
        list3.add("123");
        for (int i = 0; i < list3.size(); i++) {
            Object o = list3.get(i);
            String s = (String) o;
        }
    }
}



--------------
package com.itheima.day06.teacher.c_generics;

/**
    这里是用泛型之后
*/
public class NBA<MVP>{ //泛型定义在类上
    //作用  在类中 都可以去使用这个未知的类型
    private MVP mvp ;//MVP泛型类型 定义的时候不具体

    public MVP getMvp(){//可以当成返回值类
        return mvp;
    }

    public void setMvp(MVP mvp) {//可以作为参数类型
        this.mvp = mvp;
    }
}


------
package com.itheima.day06.teacher.c_generics;

/**
 * 测试类
 */
public class Demo01 {

    public static void main(String[] args) {
        //创建一个NBA对象
        NBA<String> nba = new NBA<>();
        nba.setMvp("恩比德");

        String mvp = nba.getMvp();
        System.out.println(mvp);

        NBA<Integer> nba2 = new NBA<>();
        nba2.setMvp(77);
        System.out.println(nba2.getMvp());
    }
}


-----------

代码演示2:

package com.itheima.day06.teacher.d_generics;

/*
  泛型只能是引用类型
 */

public class MyArrayList<E>{

    //定义底层数组变量
    private Object[] array = new Object[10];//定义初始容量

    //定义一个数组的初始索引
    private int index = 0;

    /*
       添加元素  add(E )
     */
    public void add(E e){
        array[index] = e;
        index++;
    }
    /*
        根据索引获取元素
     */
    public E get(int index){
        return (E)array[index];
    }
}


-------------
package com.itheima.day06.teacher.d_generics;

/**
 * 测试类
 */
public class Demo {

    public static void main(String[] args) {
        MyArrayList<String> list = new MyArrayList<>();

        list.add("霍霍霍");
        list.add("魁魁魁");

        String s = list.get(0);
        System.out.println(s);

    }
}

2.泛型接口

        使用了泛型定义的接口就是泛型接口

        格式:修饰符 interface 接口名称<泛型变量>{}

        作用:泛型接口可以让实现类选择当前功能需要操作的数据类型

        原理:实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对于该类型的操作。

代码演示:

package com.itheima.day06.teacher.e_generics;
/**
    泛型接口
*/
public interface MyHoliday<X>{
    //泛型定义在接口   规范方法的使用

    void eat(X x);
}

-------------
package com.itheima.day06.teacher.e_generics;

public class Student implements MyHoliday<String>{
    @Override
    public void eat(String s) {
        System.out.println("吃烧烤...吃棒棒糖  bulubiu");
    }
}


------------
package com.itheima.day06.teacher.e_generics;

import java.util.Comparator;
/**
    泛型类也可以实现泛型接口
*/
public class Teacher<X> implements MyHoliday<X>{

    @Override
    public void eat(X x) {
    }
}

3.泛型方法

定义方法时同时定义了泛型的方法就是泛型方法

格式:

作用:方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性。

代码演示:

package com.itheima.day06.teacher.f_generics;
/**
    泛型方法
*/
public class GenericsDemo {

    public static void main(String[] args) {
        String aaa = test("aaa");

        Integer test = test(12);

        Double test1 = test(1.23);
    }

    public static <T> T test(T t){

        return t;
    }
}


---------------
package com.itheima.day06.teacher.f_generics;
/**
    泛型类里定义泛型方法
*/
public class Sugar<E> {

    private E e;

    public E getE(){
        return e;
    }

    public <T> void show(T t){//泛型定义在方法上

    }

}


4.泛型通配符、上下限

        ? 可以在“使用泛型”的时候代表一切类型。

        E T K V 是在定义泛型的时候使用的。

泛型的上下限:

       1. ? extends Car: ?必须是Car或者其子类 泛型上限

       2. ? super Car : ?必须是Car或者其父类 泛型下限

 代码演示:

package com.itheima.day06.teacher.f_generics;

import java.util.ArrayList;

/*
 定义几个类
 */
class Car extends Object {
}

class BENZ extends Car {
}

class ThreeBengZi extends Car {
}


public class Test {

    public static void main(String[] args) {

        ArrayList<BENZ> list1 = new ArrayList<>();
        ArrayList<ThreeBengZi> list2 = new ArrayList<>();
        ArrayList<Car> list3 = new ArrayList<>();
        ArrayList<Object> list4 = new ArrayList<>();
        test1(list1);
        test1(list2);
        test1(list3);
        test1(list4);
        test2(list1);
        test2(list2);
        test2(list3);
        test2(list4);
        System.out.println("===================");
        System.out.println("=  只能车及其子类 可以接收========");
        test3(list1);//   ArrayList<BENZ> list1 = new ArrayList<>();
        test3(list2);//   ArrayList<ThreeBengZi> list2 = new ArrayList<>();
        test3(list3);//   ArrayList<Car> list3 = new ArrayList<>();
        //   ArrayList<Car> list3 =  new ArrayList<Car>();
        //  如果类型有泛型  类型<泛型>  整体是一个类型!!
        //  List<Car>  ArrayList<Car>
//        test3(list4);
        // <? extends Car> 泛型的类型是Car或及其子类!
        // <? super Car>   泛型的类型是Car或及其父类!
        System.out.println("=  只能车及其父类 可以接收========");
//        test4(list1);
//        test4(list2);
        test4(list3);
        test4(list4);

    }

    /*
      设计一个方法 可以接收 各种各样的集合
     */
    public static <T> void test1(ArrayList<T> list) {
        System.out.println("测试");
    }

    /*
      ? 通配符接收带有泛型集合
     */
    public static void test2(ArrayList<?> list) {
        System.out.println("测试");
    }

    public static void test3(ArrayList<? extends Car> list) {
        System.out.println("限制泛型的类型!!!!!");
    }

    public static void test4(ArrayList<? super Car> list) {
        System.out.println("限制泛型的类型!!!!!");
    }
}

最后注意事项:

泛型的注意事项:擦除问题、基本数据类型问题

        1.泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除。(大白话就是执行后生成的class文件,不在是你定义的字母,而是你传入的实际类型)

        2.泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1455694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL】变量、流程控制

一、变量 在MySQL的存储过程与函数中&#xff0c;可以使用变量来存储查询或计算的中间结果数据&#xff0c;或者输出最终的结果数据。它可以分为用户自定义变量与系统变量 1、系统变量 1&#xff09;系统变量分为全局变量&#xff08;需要使用关键字global&#xff09;和会话…

上位机图像处理和嵌入式模块部署(boost库的使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 作为c程序员来说&#xff0c;除了qt之外&#xff0c;另外值得学的开发库就是boost。boost本身包含的内容非常多&#xff0c;基本我们常用的功能都已…

linux下ffmpeg调用GPU硬件解码(VDPAU/VAAPI)保存文件

本文讲解在linux下面&#xff0c;如何通过ffmpeg调用GPU硬件解码&#xff0c;并保存解码完的yuv文件。 其实&#xff0c;ffmpeg自带的例子hw_decode.c这个文件&#xff0c;就已经能满足要求了&#xff0c;因此&#xff0c;本文就尝试讲解以下hw_decode这个例子。hw_decode.c可以…

使用vscode传入参数的方式进行debug

使用vscode传入参数的方式进行debug {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息&#xff0c;请访问: https://go.microsoft.com/fwlink/?linkid830387"version": "0.2.0","configurations": [{&quo…

【AGI视频】Sora的奇幻之旅:未来影视创作的无限可能

在五年后的未来&#xff0c;科技的发展为影视创作带来了翻天覆地的变化。其中&#xff0c;Sora视频生成软件成为了行业的翘楚&#xff0c;引领着全新的创作潮流。Sora基于先进的Transformer架构&#xff0c;将AI与人类的创造力完美结合&#xff0c;为观众带来了前所未有的视听盛…

【分享】windows11 vmware centos7 搭建k8s完整实验

概述 开年第一天&#xff0c;补充下自己的技术栈。 参考文章: k8s安装 - 知乎 【Kubernetes部署篇】K8s图形化管理工具Dasboard部署及使用_k8s可视化管理工具-CSDN博客 centos7环境下安装k8s 1.18.0版本带dashboard界面全记录&#xff08;纯命令版&#xff09;_sysconfig1.…

通俗易懂地解释OpenAI Sora视频生成的特点有哪些?与Runway Gen2、Pika有什么区别?缺点是什么?

OpenAI的Sora模型是最近两天最火热的模型。它生成的视频无论是清晰度、连贯性和时间上都有非常好的结果。在Sora之前&#xff0c;业界已经有了很多视频生成工具和平台。但为什么Sora可以引起如此大的关注&#xff1f;Sora生成的视频与此前其它平台生成的视频到底有哪些区别&…

MATLAB知识点:meshgrid函数(★★★★☆)返回二维网格坐标(在MATLAB中经常用于生成绘制三维图的数据)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第三…

入门级10寸加固行业平板—EM-I10J

亿道信息以其坚固耐用的智能终端设备而闻名&#xff0c;近日发布了一款理想入门级 10 英寸加固平板电脑—I10J。 EM-I10J​​ 这是一款 10 英寸的平板电脑&#xff0c;主要运行 Windows 10操作系统&#xff0c;带有硬化塑料外壳&#xff0c;具有 IP65 防水防尘功能和 MIL-STD 8…

踩坑实录(Fourth Day)

今天开工了&#xff0c;其实还沉浸在过年放假的喜悦中……今天在自己写 Vue3 的项目&#xff0c;虽说是跟着 B 站在敲&#xff0c;但是依旧是踩了一些个坑&#xff0c;就离谱……照着敲都能踩到坑&#xff0c;我也是醉了…… 此为第四篇&#xff08;2024 年 02 月 18 日&#x…

2024免费版EasyRecovery软件有哪些功能限制?

EasyRecovery软件的主要功能包括&#xff1a; 数据恢复&#xff1a;这是EasyRecovery软件的核心功能。它可以恢复因各种原因丢失或删除的数据&#xff0c;无论是由于磁盘格式化、文件删除还是其他因素。EasyRecovery使用高级的数据恢复算法&#xff0c;能够快速扫描整个磁盘&a…

python绘制k线图均线图

AAPL.csv 数据文件 Date,Close,Volume,Open,High,Low 06/23/2023,$186.68,53117000,$185.55,$187.56,$185.01 06/22/2023,$187.00,51245330,$183.74,$187.045,$183.67 06/21/2023,$183.96,49515700,$184.90,$185.41,$182.5901 06/20/2023,$185.01,49799090,$184.41,$1…

互联网加竞赛 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习多目标跟踪 …

基于Doris构建亿级数据实时数据分析系统

背景 随着公司业务快速发展&#xff0c;对业务数据进行增长分析的需求越来越迫切&#xff0c;与此同时我们的业务数据量也在快速激增、每天的数据新增量大概在30w 左右&#xff0c;一年就会产生1 个亿的数据&#xff0c;显然基于传统MySQL数据库已经无法支撑满足以上需求 基于上…

《Linux 简易速速上手小册》第2章: 命令行的艺术(2024 最新版)

文章目录 2.1 基本 Linux 命令2.1.1 重点基础知识2.1.2 重点案例&#xff1a;整理下载文件夹2.1.3 拓展案例 1&#xff1a;批量重命名文件2.1.4 拓展案例 2&#xff1a;查找并删除特定文件 2.2 文件和目录管理2.2.1 重点基础知识2.2.2 重点案例&#xff1a;部署一个简单的网站2…

RabbitMQ鉴权设计以及相关探讨

文章目录 1. rabbitmq的鉴权设计2. rabbitmq鉴权应用范围3. rabbitmq鉴权的常用方法3.1 用户管理3.2 角色管理3.3 权限管理 4. 默认鉴权4.1 默认用户4.2 默认角色 5. 参考文档 鉴权&#xff0c;分别由鉴和权组成 鉴&#xff1a; 表示身份认证&#xff0c;认证相关用户是否存在…

AlexNet的出现推动深度学习的巨大发展

尽管AlexNet&#xff08;2012&#xff09;的代码只比LeNet&#xff08;1998&#xff09;多出几行&#xff0c;但学术界花了很多年才接受深度学习这一概念&#xff0c;并应用其出色的实验结果。 AlexNet&#xff08;由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton共同设计…

Docker原理及概念相关

Docker最核心的组件 image&#xff1a;镜像&#xff0c;构建容器&#xff0c;也可以通过Dockerfile文本描述镜像的内容。 (我们将应用程序运行所需的环境&#xff0c;打包为镜像文件) Container&#xff1a;容器 (你的应用程序&#xff0c;就跑在容器中 ) 镜像仓库(dockerhub)(…

Java学习笔记2024/2/18

1.API 1.1API概述 什么是API API (Application Programming Interface) &#xff1a;应用程序编程接口 java中的API 指的就是 JDK 中提供的各种功能的 Java类&#xff0c;这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只需要学习这…

kali无线渗透之蓝牙原理与探测与侦听

“传统蓝牙”规范在2.4GHz的ISM波段上定义了79个信道&#xff0c;每个信道有1MHz的带宽。设备在这些信道中以每秒1600次的频率进行跳转&#xff0c;换句话说&#xff0c;就是每微秒625次跳转。这项信道跳转技术被称为“跳频扩频”(Frequency HoppingSpread Spectrum&#xff0c…