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();// Objectlist3.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>{@Overridepublic 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>{@Overridepublic 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.rhkb.cn/news/260013.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 使用QScintilla 编辑lua 脚本

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

Yii2项目使用composer异常记录

问题描述 在yii2项目中&#xff0c;使用require命令安装依赖时&#xff0c;出现如下错误提示 该提示意思是&#xff1a;composer运行时&#xff0c;执行了yiisoft/yii2-composer目录下的插件&#xff0c;但是该插件使用的API版本是1.0&#xff0c;但是当前的cmposer版本提供的…

Selenium实现多页面切换

当使用 Selenium 进行自动化测试或爬取数据时&#xff0c;有时需要处理多个页面之间的切换。以下是一些可能需要多页面切换的情况&#xff1a; 1、打开新窗口/页面&#xff1a; 在当前页面上点击链接、按钮或执行某些操作时&#xff0c;可能会打开一个新的窗口或页面。此时&a…

MySQL 基础知识(六)之数据查询(一)

目录 1 基本查询 1.1 查询相关列 (select * / 列名) 1.2 别名 (as) 1.3 去重 (distinct) 1.4 对列中的数据进行运算 (、-、*、/) 2 条件查询 (where) 2.1 等值查询 () 2.2 非等值查询 (>、<、>、<、!、><) 2.3 逻辑判断 (and、or、not) 2.4 区间判…

matlab发送串口数据,并进行串口数据头的添加,我们来看下pwm解析后并通过串口输出的效果

uintt16位的话会在上面前面加上00&#xff0c;16位的话一定是两个字节&#xff0c;一共16位的数据 如果是unint8的话就不会&#xff0c; 注意这里给的是13&#xff0c;但是现实的00 0D&#xff0c;这是大小端的问题&#xff0c;在matlanb里设置&#xff0c;我们就默认用这个模式…

更快找到远程/自由工作的网站

不要使用Fiver或Upwork。 它们已经饱和了。 下面是10个更快找到远程/自由工作的网站&#xff1a; 1. Toptal 这个网站专门为熟练的自由职业者提供远程工作机会&#xff0c;如Shopify和Priceline等一流公司。 他们只接受软件开发、设计和金融等领域的顶级3%自由职业者。 htt…

普中51单片机学习(九)

蜂鸣器 蜂鸣器简介 在单片机应用的设计上&#xff0c;很多方案都会用到蜂鸣器&#xff0c;大部分都是使用蜂鸣器来做提示或报警&#xff0c;比如按键按下、开始工作、工作结束或是故障等等。改变单片机引脚输出波形的频率&#xff0c;就可以调整控制蜂鸣器音调&#xff0c;产…

问题:从完整的问题解决过程来看,( )是首要环节。A.理解问题 B.提出假设C.发现问题 D.检验假设 #学习方法#学习方法

问题&#xff1a;从完整的问题解决过程来看&#xff0c;&#xff08; &#xff09;是首要环节。A&#xff0e;理解问题 B&#xff0e;提出假设C&#xff0e;发现问题 D&#xff0e;检验假设 A.理解问题 B.提出假设 C&#xff0e;发现问题 参考答案如图所示

Eclipse - Switch Workspace

Eclipse - Switch Workspace References Switch Workspace References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

代码随想录算法训练营DAY20 | 二叉树 (8)

一、LeetCode 701 二叉搜索树中的插入操作 题目链接&#xff1a; 701.二叉搜索树中的插入操作https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/ 思路&#xff1a;见缝插针罢辽。 class Solution {public TreeNode insertIntoBST(TreeNode root, i…

vue3项目配置按需自动导入API组件unplugin-auto-import

场景应用&#xff1a;避免写一大堆的import&#xff0c;比如关于Vue和Vue Router的 1、安装unplugin-auto-import npm i -D unplugin-auto-import 2、配置vite.config import AutoImport from unplugin-auto-import/vite//按需自动加载API插件 AutoImport({ imports: ["…

掘根宝典之C++深复制与浅复制(复制构造函数,默认复制构造函数)

到目前为止我们已经学了构造函数&#xff0c;默认构造函数&#xff0c;析构函数&#xff1a;http://t.csdnimg.cn/EOQxx 转换函数&#xff0c;转换构造函数&#xff1a;http://t.csdnimg.cn/kiHo6 友元函数&#xff1a;http://t.csdnimg.cn/To8Tj 接下来我们来学习一个新函数…

数据传输稳如山,郑州大象陶瓷展文物预防性保护更安心

​一、“人间烟火——古代陶瓷中的衣食住行”郑州展览 2月8日&#xff0c;郑州大象瓷博物馆与郑州紫荆山公园协作&#xff0c;呈现了一场独特的文化盛会。“人间烟火——古代陶瓷中的衣食住行”展览正式拉开帷幕&#xff0c;为市民和游客带来了穿越历史、贯穿古今的文化体验。…

11. Springboot集成Dubbo3(二)示例demo

目录 1、前言 2、注册中心 3、快速开始 3.1、添加dubbo3依赖 3.2、dubbo3-api ​编辑 3.3、dubbo3-server 3.3.1、添加依赖 3.3.2、实现IUserService 3.3.3、添加配置文件application.properties 3.3.4、修改Application启动类 3.3.5、出错解决 3.4、dubbo3-porta…

【零基础学习CAPL】——CAN报文的发送(面板中直接修改信号值进行发送)

🙋‍♂️【零基础学习CAPL】系列💁‍♂️点击跳转 文章目录 1.概述2.面板创建3.系统变量创建4.系统变量与Panel值绑定4.CAPL实现5.效果6.全量脚本1.概述 在前面文章”【零基础学习CAPL】——CAN报文的发送(按下按钮同时周期性发送)“中对于发送报文中的信号是在脚本中固…

Nodejs 第三十八章(mysql2)

在之前的篇章中&#xff0c;已经补充完成mysql的基本知识&#xff0c;那么现在开始&#xff0c;我们需要把mysql和express,nodejs连接起来。 安装依赖 npm install mysql2 express js-yamlmysql2 用来连接mysql和编写sq语句express 用来提供接口 增删改差js-yaml 用来编写配置…

PyCharm 取消所有断点

PyCharm 取消所有断点 1. Run -> View Breakpoints...2. Python Line Breakpoint3. Remove - DoneReferences 1. Run -> View Breakpoints… 2. Python Line Breakpoint ​​​ 3. Remove - Done References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【day01】每天三道 java后端面试题:JDK、JRE和JVM | 字节码 | ACID

文章目录 1. JDK, JRE, JVM分别是什么&#xff1f;有什么区别&#xff1f;2. 什么是字节码&#xff1f;采用字节码的最大好处是什么&#xff1f;3. 什么是数据库事务&#xff1f;讲一下事务的ACID特性。 1. JDK, JRE, JVM分别是什么&#xff1f;有什么区别&#xff1f; 答题思路…

linux安装mysql8且初始化表名忽略大小写

mysql8下载地址 MySQL8.0安装步骤 1、把安装包上传到linux系统&#xff0c;解压、重命名并移动到/usr/local/目录&#xff1a; cd ~ tar -xvf mysql-8.0.32-linux-glibc2.12-x86_64.tar.xz mv mysql-8.0.32-linux-glibc2.12-x86_64/ mysql80/ mv mysql80/ /usr/local/2、在M…

C/C++内存管理详解

目录 一、C内存分布 二、C语言与C内存管理方式 1、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 2、C中的内存管理方式&#xff1a;new/delete 三、operator new与operator delete函数 1、函数概念&#xff1a; 2、函数使用&#xff1a; 3、底层原理…