java的泛型【详解】

定义类、接口、方法时,同时声明了一个或者多个类型变量(如:<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.泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mac M1芯片编译openjdk报错问题解决

使用命令&#xff1a; sudo sh configure --with-target-bits64 用mac m1芯片编译openjdk一直报错&#xff1a; configure: The tested number of bits in the target (64) differs from the number of bits expected to be found in the target (32) configure: error: Cann…

C++ 调用js 脚本

需求&#xff1a; 使用Qt/C 调用js 脚本。Qt 调用lua 脚本性能应该是最快的&#xff0c;但是需要引入第三方库&#xff0c;虽然也不是特别麻烦&#xff0c;但是调用js脚本&#xff0c;确实内置的功能&#xff08;C 调用lua 脚本-CSDN博客&#xff09; 步骤&#xff1a; 1&…

零基础搭建 Kubernetes 集群

零基础搭建 Kubernetes 集群 1、简介 在数字化时代&#xff0c;容器技术已经变成了软件开发和部署的标准&#xff0c;而在众多容器管理工具中&#xff0c;Kubernetes&#xff08;简称为 K8s&#xff09;凭借其高效的资源管理、弹性伸缩和自我修复的能力&#xff0c;成为了行业…

三防平板电脑丨亿道工业三防平板丨三防平板定制丨机场维修应用

随着全球航空交通的增长和机场运营的扩展&#xff0c;机场维护的重要性日益凸显。为确保机场设施的安全和顺畅运行&#xff0c;采取适当的措施来加强机场维护至关重要。其中&#xff0c;三防平板是一种有效的工具&#xff0c;它可以提供持久耐用的表面保护&#xff0c;使机场维…

最简单的基于 FFmpeg 的视频编码器(YUV 编码为 HEVC(H.265))

最简单的基于 FFmpeg 的视频编码器&#xff08;YUV 编码为 HEVC&#xff08;H.265&#xff09;&#xff09; 最简单的基于 FFmpeg 的视频编码器&#xff08;YUV 编码为 HEVC&#xff08;H.265&#xff09;&#xff09;正文结果工程文件下载 最简单的基于 FFmpeg 的视频编码器&a…

【开源】SpringBoot框架开发高校宿舍调配管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统展示四、核心代码4.1 查询单条个人习惯4.2 查询我的室友4.3 查询宿舍4.4 查询指定性别全部宿舍4.5 初次分配宿舍 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的…

基于ESP32+Platformio的物联网RTOS_SDK-CC_Device

本项目基于ESP32以及Platformio平台开发&#xff0c;请自行查阅如何配置这个环境 开源gitee地址&#xff1a;cc_smart_device 如果愿意贡献项目or提出疑问和修改的&#xff0c;请在gitee上提issue 文章目录 1 基本介绍2 基本架构3 中间件3.1 RTOS部分3.1.1 互斥锁3.1.2 信号量3…

Academic Inquiry|投稿状态分享(ACS,Wiley,RSC,Elsevier,MDPI,Springer Nature出版社)

作为科研人员&#xff0c;我们经常会面临着向学术期刊投稿的问题。一般来说&#xff0c;期刊的投稿状态会在官方网站上进行公示&#xff0c;我们可以通过期刊的官方网站或者投稿系统查询到我们投稿的论文的状态&#xff0c;对于不同的期刊在投稿系统中会有不同的显示。 说明&am…

Eclipse - Format Comment

Eclipse - Format & Comment 1. Correct Indentation2. Format3. Toggle Comment4. Add Block Comment5. Remove Block CommentReferences 1. Correct Indentation Ctrl A: 选择全部代码 Ctrl I: 校正缩进 or right-click -> Source -> Correct Indentation 2. F…

Qt 使用QScintilla 编辑lua 脚本

需求&#xff1a; 利用QScintilla 编辑lua 脚本 步骤&#xff1a; 1&#xff0c;下载 QScintilla Riverbank Computing | Download 2, 打开 src/qscintilla.pro 文件 编译出 dll库 3&#xff0c;工程中引入这个库 注意debug 模式 必须加载debug 版本编译的库&#xff0…

Eclipse - Colors and Fonts

Eclipse - Colors and Fonts References 编码最好使用等宽字体&#xff0c;Ubuntu 下自带的 Ubuntu Mono 可以使用。更换字体时看到名字里面带有 Mono 的基本都是等宽字体。 Window -> Preferences -> General -> Appearance -> Colors and Fonts -> C/C ->…

沁恒CH32V30X学习笔记01--创建工程

资料下载 https://www.wch.cn/products/CH32V307.html? 下载完成后安装MounRiver Studio(MRS) 创建工程 修改时钟144M printf重定向 修改外部晶振频率位置 添加自定义文件 添加目录

HttpClient:HTTP GET请求的服务器响应输出

前言 在现代软件开发中&#xff0c;与网络通信相关的技术变得愈发重要。Java作为一种强大而灵活的编程语言&#xff0c;提供了丰富的工具和库&#xff0c;用于处理各种网络通信场景。本文将聚焦在Java中使用HttpClient库发送HTTP GET请求&#xff0c;并将服务器的响应数据进行…

《游戏引擎架构》--学习

内存管理 优化动态内存分配 维持最低限度的堆分配&#xff0c;并且永不在紧凑循环中使用堆分配 容器 迭代器 未完待续。。。

IDEA2021版热部署配置

第一步 Settings中搜索compiler 勾选上Build project automatically 第二步 按快捷键 CtrlAltShift/ 选择第一个Registry 勾选上 注&#xff1a;2021版IDEA 被迁移到了这里 第三步 第四步 pom.xml中添加 配置文件中添加 #springdevtools spring.devtools.restart.…

Python打发无聊时光:3.实现简单电路的仿真

看到这个标题肯定有人会问&#xff1a;好好的multisim、 proteus之类的专门电路仿真软件不用&#xff0c;非要写一个简陋的python程序来弄&#xff0c;是不是精神失常了。实际上&#xff0c;我也不知道为什么要这么干&#xff0c;前两篇文章是我实际项目中的一些探索&#xff0…

standalone安装部署

standalone是spark的资源调度服务&#xff1b;作用和yarn是一样的&#xff1b;standlone运行时的服务&#xff1a; master服务&#xff1b;主服务&#xff1b;管理整个资源调度&#xff1b;资源的申请需要通过master进行分配&#xff1b;类似于yarn里的ResourceManager;&#x…

BufferedImage 这个类在jdk17中使用哪个import导入

在Java开发中&#xff0c;BufferedImage 类是用于处理图像数据的一个类。在JDK 17中&#xff0c;BufferedImage 类属于 java.awt.image 包。因此&#xff0c;要在你的Java程序中使用 BufferedImage 类&#xff0c;你需要通过以下方式导入该类&#xff1a; import java.awt.ima…

Maven - Plugins报错的正确解决之道

背景&#xff1a; 正确解决之道&#xff1a; 在自己本地Maven的安装目录中找到自己的仓库地址目录&#xff1a;直接搜索自己报错的插件文件&#xff0c;把它们删除&#xff0c;如图&#xff1a; 接着回到IDEA点击Maven刷新按钮重新加载即可&#xff1a;已解决 反例&#xff1…

RabbitMQ保证消息的可靠性

1. 问题引入 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送时丢失&#xff1a; 生产者发送的消息未送达exchange消息到达exchange后未到达queue MQ宕机&…