当前位置: 首页 > news >正文

【什么是泛型,有什么好处】

在这里插入图片描述

✅什么是泛型,有什么好处

  • ✅典型回答
  • ✅泛型是如何实现的
    • ✅什么是类型擦除?
    • 📝C语言对泛型的支持
    • 📝泛型擦除的缺点有哪些?
  • ✅对泛型通配符的理解
    • 📝泛型中上下界限定符 extends 和 super 有什么区别?
    • ✅List<?>,List<Object>,List之间的区别?
    • ✅在泛型为Integer的ArrayList中存放一个String类型的对象
    • ✅对数组协变和泛型非协变的理解

✅典型回答

Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(typeparameter)。声明的类型参数在使用时用具体的类型来替换。泛型最主要的应用是在JDK 5中的新集合类框架中。




泛型的好处有两个:


1、方便: 可以提高代码的复用性。以List接口为例,我们可以将String、Integer等类型放入List中,如不用泛型,存放String类型要写一个List接口,存放Integer要写另外一个List接口,泛型可以很好的解决这个问题。


2、安全: 在泛型出之前,通过Object实现的类型转换需要在运行时检查,如果类型转换出错,程序直接GG,可能会带来毁灭性打击。而泛型的作用就是在编译时做类型检查,这无疑增加程序的安全性。


✅泛型是如何实现的


Java中的泛型通过类型擦除的方式来实现,通俗点理解,就是通过语法糖的形式,在java->.class转换的阶段,将List擦除调转为List的手段。换句话说,Java的泛型只在编译期,Jm是不会感知到泛型的。

✅什么是类型擦除?


类型擦除是Java在处理泛型的一种方式,如Java的编译器在编译以下代码时:


public class Foo<T> {T bar;void doSth(T param) {}
};
Foo<String> f1;
Foo<Integer> f2;

在编译后的字节码文件中,会把泛型的信息擦除掉:


public class Foo {Object bar;void dosth(Object param) {}
};

也就是说,在代码中的Foo 和 Foo使用的类,经过编译后都是同一个类。


所以说泛型技术实际上是Java语言的一颗语法糖,因为泛型经过编译器处理之后就被擦除了。


这种擦除的过程,被称之为一类型擦除。所以类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且在必要的时候添加类型检查和类型转换的方法。


类型擦除可以简单的理解为将泛型iava代码转换为普通iava代码,只不过编译器更直接点,将泛型iava代码直接转换成普通iava字节码。


📝C语言对泛型的支持


泛型是一种编程范式,在不同的语言和编译器中的实现和支持方式都不一样。


通常情况下,一个编译器处理泛型有多种方式,在C++中,当编译器对以下代码编译时。

template <typename T> struct Foo {T bar;void doSth(T param) {}
};Foo<int> f1;
Foo<float> f2;

当编译器对其进行编译时,编译器发现要用到Foo和Foo,这时候就会为每一人泛型类新生成一份执行代码。相当于新创建了如下两个类:


struct FooInt {int bar;void doSth(int param) {}
};struct FooFloat {float bar;void doSth(float param) {}
};

这种做法,用起来的时候很方便,只需要根据具体类型找到具体的的类和方法就行了。但是问题是,当我们多次使用不同类型的模板时,就会创建出来的很多新的类,就会导致代码膨胀。

📝泛型擦除的缺点有哪些?


1.泛型不可以重载


2.泛型异常类不可以多次catch


3.泛型类中的静态变量也只有一份,不会有多份。


✅对泛型通配符的理解


📝泛型中上下界限定符 extends 和 super 有什么区别?


<? extends T>表示类型的上界,表示参数化类型的可能是T 或是 T的子类。

// 定义一个泛型方法,接受任何继承自Number的类型
public <T extends Number> void processlumber(T number) {// 在这个方法中,可以安全地调用Number的方法double value = number .doubleValue( );// 其他操作...
}

<? super T> 表示类型下界 (Java Core中叫超类型限定),表示参数化类型是此类型的超类型 (父类型),直至Obiect

//定义一个泛型方法,接受任何类型的List,并向其中添加元素
public <T> void addElements(List<? super T> list, T element) {list.add(element);// 其他操作...
}

在使用限定通配符的时候,需要遵守PECS原则,即producer Extends,Consumer Super; 上界生产,下界消费。


如果要从集合中读取类型T的数据,并目不能写入,可以使用 ? extends 通配符;(Producer Extends),如上面的processNumber方法。


使用extends 的时候是可读取不可写入,那为什么叫上界生产呢?
答:因为这个消费者/生产者描述的<集合>,当我们从集合读取的时候,集合是生产者。




如果既要存又要取,那么就不需要使用任何的通配符。


✅List<?>,List,List之间的区别?

1、List<?>是一个末知类型的List,而List < object> 其实是任意类型的List。可以把List< String>,List< Integer>赋值给List<?>,却不能把List< String>赋值给 List< Object>。
2、可以把任何带参数的类型传递给原始类型List,但却不能把List< String>赋值给List< Obiect>,因为会产生编译错误(不支持协变)

✅在泛型为Integer的ArrayList中存放一个String类型的对象


通过反射可以实现:


public void test() throws Exception {ArrayList<Integer> list = new ArrayList<Integer>();Method method = list.getClass().getMethod("add"Object.class);method.invoke(list,"Java反射机制实例”);System.out.println(list.get(0));
}

✅对数组协变和泛型非协变的理解


所胃协变,可以简单理解为因为Object是String的父类,所以Object1同样是Stringl的父类,这种情况Java是允许的;但是对于泛型来说,List< Obiect>和List< String>半毛钱关系都没有


为什么要这样设计呢,如果泛型允许协变(实际上以下代码第一步就会编译失败),考虑如下例子:


List<Object> a = new List<String>();
a.add(1); // 允许协变,可以装进来
String s = a.get(0); // 编译报错

但是,为什么泛型不允许协变,而数组允许协变呢? 原因有二 :


1 . 因为数组设计之初没有泛型,为了兼容考虑,如 Arrays.equals(object[],object[]) 方法,是时代无奈的产物

2 . 数组也属于对象,它记录了引用实际的类型,再放入数组的时候,如果类型不一样就会报错,而不是等到拿出来的时候才发现问题,相对来说安全一些。

相关文章:

【什么是泛型,有什么好处】

✅什么是泛型&#xff0c;有什么好处 ✅典型回答✅泛型是如何实现的✅什么是类型擦除&#xff1f;&#x1f4dd;C语言对泛型的支持&#x1f4dd;泛型擦除的缺点有哪些&#xff1f; ✅对泛型通配符的理解&#x1f4dd;泛型中上下界限定符 extends 和 super 有什么区别&#xff1…...

Stable Diffusion系列(三):网络分类与选择

文章目录 网络分类模型基座模型衍生模型二次元模型2.5D模型写实风格模型 名称解读 VAELora嵌入文件放置界面使用 网络分类 当使用SD webui绘图时&#xff0c;为了提升绘图质量&#xff0c;可以多种网络混合使用&#xff0c;可选的网络包括了模型、VAE、超网络、Lora和嵌入。 …...

Twincat中PLC的ST语言编程实现机器人安全交互

在TwinCAT中&#xff0c;使用ST语言&#xff08;Structured Text&#xff09;进行PLC编程是一种常见的做法。 机器人接触力超过预设阈值后执行停止动作 为了实现机器人在接触力超过预设阈值后停止动作的功能&#xff0c;你需要编写一段ST语言代码&#xff0c;以检查当前的接触…...

Redis实现日榜|直播间榜单|排行榜|Redis实现日榜01

前言 直播间贡献榜是一种常见的直播平台功能&#xff0c;用于展示观众在直播过程中的贡献情况。它可以根据观众的互动行为和贡献值进行排名&#xff0c;并实时更新&#xff0c;以鼓励观众积极参与直播活动。 在直播间贡献榜中&#xff0c;每个观众都有一个对应的贡献值&#…...

如何使用内网穿透工具实现Java远程连接本地Elasticsearch搜索分析引擎

文章目录 前言1. Windows 安装 Cpolar2. 创建Elasticsearch公网连接地址3. 远程连接Elasticsearch4. 设置固定二级子域名 前言 简单几步,结合Cpolar 内网穿透工具实现Java 远程连接操作本地分布式搜索和数据分析引擎Elasticsearch。 Cpolar内网穿透提供了更高的安全性和隐私保…...

C语言数据结构-----常用七种排序介绍、分类、实现及性能比较

前言 ①排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 ②稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&#…...

2023年山东省职业院校技能大赛高职组 “软件测试”赛项竞赛任务四 单元测试

任务四 单元测试 任务要求 题目1&#xff1a;任意输入2个正整数值分别存入x、y中&#xff0c;据此完成下述分析&#xff1a;若x≤0或y≤0&#xff0c;则提示&#xff1a;“输入不符合要求。”&#xff1b;若2值相同&#xff0c;则提示“可以构建圆形或正方形”&#xff1b;若2…...

在Redis客户端设置连接密码 并演示密码登录

我们先连接到Redis服务 然后 我们要输入 CONFIG SET requirepass “新密码” 例如 CONFIG SET requirepass "A15167"这样 密码就被设置成立 A15167 我们 输入 AUTH 密码 例如 AUTH A15167这里 返回OK说明成功了 然后 我们退出在登录就真的需要 redis-cli -h IP地…...

阿里云公有云平台

1. 请简要介绍一下公有云平台的基本概念和特点。 公有云是一种云计算模型&#xff0c;其中服务器、网络和存储资源等IT基础架构以虚拟资源的形式提供&#xff0c;并且可以通过互联网进行访问。这些资源是由第三方提供商共享并提供给用户的&#xff0c;包括计算、存储、网络等。…...

Zookeeper的学习笔记

Zookeeper概念 Zookeeper是一个树形目录服务&#xff0c;简称zk。 Zookeeper是一个分布式的、开源的分布式应用程序的协调服务 Zookeeper提供主要的功能包括&#xff1a;配置管理&#xff0c;分布式锁&#xff0c;集群管理 Zookeeper命令操作 zk数据模型 zk中的每一个节点…...

leetcode2两数加和问题(链表)

题目思路&#xff1a; ①创建一个int类型的局部变量&#xff0c;用来存储两个结点的Val值。 ②判断该Val值与10求余(mod)后是否大于0,如果大于0, 则需要在下一个结点进位。 ③最关键的步骤&#xff1a;实现l1&#xff0c;l2结点数值相加后构建新的存储求和后的结点&#xff0…...

VSCode中配置prettier和ESLint

文章目录 了解ESLint和Prettier的作用prettier配置ESLint配置常见问答ESLint 和Prettier 有什么区别&#xff1f;为什么我应该同时使用ESLint 和Prettier&#xff1f;在使用ESLint 和Prettier 时&#xff0c;有可能出现它们之间的规则冲突吗&#xff1f;我已经在项目中使用了ES…...

如何将本地websocket发布至公网并实现远程访问服务端

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…...

分享 | 软件测试的基本流程是什么?软件测试流程详细介绍

软件测试 软件测试和软件开发一样&#xff0c;是一个比较复杂的工作过程&#xff0c;如果无章法可循&#xff0c;随意进行测试势必会造成测试工作的混乱。为了使测试工作标准化、规范化&#xff0c;并且快速、高效、高质量地完成测试工作&#xff0c;需要制订完整且具体的测试…...

浮点数的转换--IEEE 754

IEEE754标准是一种浮点数表示标准&#xff0c;一般分为 单精度&#xff08;32位的二进制数&#xff09;&#xff1b;双精度&#xff08;64位的二进制数&#xff09; 根据国际标准IEEE754&#xff0c;任意一个二进制浮点数V可以表示为下面形式&#xff1a; V (-1)^s *&#…...

若依框架介绍

RuoYi&#xff08;若依&#xff09;是一款基于Spring Boot、Spring Cloud等开源框架搭建的企业级开发平台&#xff0c;旨在提供全面的解决方案&#xff0c;简化企业级应用开发&#xff0c;提高开发效率。 主要特点&#xff1a; 1. 模块化设计 RuoYi采用模块化的设计&#xff0…...

iMazing2024免费版iOS移动设备管理软件

以自己的方式管理iPhone&#xff0c;让备受信赖的软件为您传输和保存音乐、消息、文件和数据。安全备份任何 iPhone、iPad 或 iPod touch。iMazing 功能强大、易于使用&#xff0c;称得上是 Mac 和 PC 上最好的 iOS 设备管理器。 正在为iTunes繁琐的操作发愁&#xff1f;设备数…...

Zookeeper整合Java实战,不同客户端使用汇总

Java学习面试指南&#xff1a;https://javaxiaobear.cn ZooKeeper应用的开发主要通过Java客户端API去连接和操作ZooKeeper集群。可供选择的Java客户端API有&#xff1a; ZooKeeper官方的Java客户端API。 第三方的Java客户端API&#xff0c;比如Curator。 ZooKeeper官方的客户…...

【python】Ubuntu下安装spyder及matplotlib中文显示

一、查看Ubuntu版本 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy尝试用cat /etc/debian_version命令&#xff0c;竟然可以显示出来Debian的版本。 $ cat /etc/debian_version …...

Vue中操作dom,jQuery添加css类,document对象不可使用

...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...