一篇文章带你弄懂Java集合的泛型

目录

第一问:什么是泛型?有什么好处?

第二问:泛型是如何实现的呢?

第三问:类型擦除的缺点有哪些?

第四问:泛型中上下界限定符extends和super有什么区别?

第五问:List、List、List之间的区别?

第六问:如何在泛型为Integer的ArrayList中存放一个String类型的对象?


我们用问面试题的方式来讲解集合的泛型概念,这样方便读者理解。

第一问:什么是泛型?有什么好处?

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

泛型的好处有两个:

  1. 方便:可以提高代码的复用性。以List接口为例,我们可以将String、Integer等类型放入List中,如不用泛型,存放String类型要写一个List接口,存放Integer要写另外一个List接口,泛型可以很好的解决这个问题。
  2. 安全:在泛型出现之前,通过Object实现的类型转换需要在运行时检查,如果类型转换出错,程序直接GG,可能会带来毁灭性打击。而泛型的作用就是在编译时做类型检查,这无疑增加程序的安全性。

第二问:泛型是如何实现的呢?

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

比如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<String> 和 Foo<Integer>使用的类,经过编译后都是同一个类。

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

这种擦除的过程,被称之为——类型擦除。所以类型擦除指的是通过类型参数名T,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型变量的相关信息,并在仅需要的时候插入类型标记和类型转换的方法。

第三问:类型擦除的缺点有哪些?

  1. 泛型不可以重载
  2. 泛型异常类不可以多次catch
  3. 泛型类中的静态变量也只有一份,不会有多份

第四问:泛型中上下界限定符extends和super有什么区别?

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

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


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

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

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

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

如果是从集合中写入类型T的数据,并且不需要读取,可以使用<? super 通配符; (Consumer Super),如上面的addElements方法。

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

第五问:List<?>、List<Object>、List之间的区别?

  1. List<?> 是一个未知类型的List,而List<Object> 其实是任意类型的List。可以把List<String>、List<Integer>赋值给List<?>,却不能把List<String>赋值给List<Object>

  2. 可以把任何带参数的类型传递给原始类型List,但却不能把List<String>赋值给List<Object>,因为会产生编译错误(不支持协变)。

  3. List<?>由于不确定列表中元素的具体类型,因此只能从这种列表中读取数据,而不能往里面添加除了null之外的任何元素。

public class Test {public static void main(String[] args) {List<String> list = new ArrayList<>();test(list);// 编译出错test1(list);test2(list);test3(list);}public static void test(List list) {list.add("CLAY");list.add(666);}public static void test1(List<Object> list) {list.add(new Test());}public static void test2(List<?> list) {// 编译出错list.add("CLAY");// 编译正常list.get(0);}public static void test3(List<String> list) {list.add("CLAY");}
}

第六问:如何在泛型为Integer的ArrayList中存放一个String类型的对象?

通过反射可以实现:

List<Integer> list = new ArrayList<>();
Method method = list.getClass().getMethod("add", Object.class);
method.invoke(list, "Java反射机制实例");
System.out.println(list.get(0));

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

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

相关文章

HR人才测评,如何做中层管理人员的素质测评?

中层管理人员是企业中的重要力量&#xff0c;他们是连接高层管理和基层员工的桥梁&#xff0c;对企业的发展至关重要。因此&#xff0c;对中层管理人员的素质测评尤为重要。下面&#xff0c;我将介绍一些HR人才测评的方法和步骤&#xff0c;以帮助企业准确评估中层管理人员的素…

中信银行积极开展2024年金融科技活动周宣传活动

近日&#xff0c;2024年全国金融“科技活动周”正式启动。中信银行围绕“弘扬科学家精神 激发全社会创新活力”为主题&#xff0c;积极面向公众宣传各类金融知识&#xff0c;全面营造热爱科学、崇尚科学的社会氛围。 自5月25日起&#xff0c;中信银行通过全国网点大屏播放宣传…

【C++】77组合

给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 使用回溯算法。我们可以按照以下步骤来实现&#xff1a; 创建一个辅助函数 backtrack&#xff0c;用来进行回溯搜索。其中包括当前组合的状态变量 current、起始…

C# list集合

一、list集合基本使用 1.添加元素 ① 单个元素添加 List<int> list new List<int>();for (int i 0; i < 3; i){list.Add(i);}//输出&#xff1a;0,1,2 ②初始化时添加元素 List<int> list2 new List<int> { 1, 2, 3 };//输出&#xff1a;0,1…

Jenkins从放弃到入门:部署、配置与应用

目录 Jenkins详解 一、Jenkins介绍 1、Jenkins 功能 2、Jenkins 概念 3、Jenkins 目的 4、Jenkins 特性 5、产品发布流程 二、Jenkins CI/CD 流程 三、部署Jenkins git 1、jenkins 安装 yum 安装 jenkins *jenkins 依赖 java 环境 #注意2.346之后的版本不再支持jdk…

RabbitMQ-发布/订阅模式

1、发布/订阅模式介绍 在普通的生产者、消费者模式&#xff0c;rabbitmq会将消息依次传递给每一个消费者&#xff0c;一个worker一个&#xff0c;平均分配&#xff0c;这就是Round-robin调度方式&#xff0c;为了实现更加复杂的调度&#xff0c;我们就需要使用发布/订阅的方式…

EXSI虚拟机新增磁盘并将空间扩充到已有分区

这里写自定义目录标题 1、在EXSI虚拟机中新增一块磁盘配置大小2、确认新磁盘3、格式化新分区4、添加新分区到LVM5、将新增分区添加到已有分区里 1、在EXSI虚拟机中新增一块磁盘配置大小 注意事项&#xff1a; (1)需确保虚拟机已关闭活处于维护模式&#xff0c;避免数据丢失 (2…

Spring Boot详解:深入了解与实践

文章目录 1. Spring Boot简介1.1 什么是Spring Boot&#xff1f;1.2 Spring Boot的历史背景1.3 Spring Boot的核心特点 2. Spring Boot的核心概念2.1 自动配置2.1.1 自动配置原理2.1.2 自定义配置 2.2 Spring Boot Starter2.3 Spring Boot CLI 3. Spring Boot的主要功能模块3.1…

网桥、路由器和网关有什么区别

在计算机网络领域&#xff0c;网桥、路由器和网关都是常见的网络设备&#xff0c;它们在网络通信中扮演着不同的角色。虽然它们都有连接不同网络的功能&#xff0c;但在实际应用中却具有各自独特的作用和特点。 1.网桥&#xff08;Bridge&#xff09; 定义&#xff1a;网桥是…

最佳 Mac 数据恢复:恢复 Mac 上已删除的文件

尝试过许多 Mac 数据恢复工具&#xff0c;但发现没有一款能达到宣传的效果&#xff1f;我们重点介绍最好的 Mac 数据恢复软件 没有 Mac 用户愿意担心数据丢失&#xff0c;但您永远不知道什么时候会发生这种情况。无论是意外删除 Mac 上的重要文件、不小心弄湿了 Mac、感染病毒…

CSS:list-style作用

list-style作用 介绍属性1. list-style-type2.list-style-image3.list-style-position 常见用法1.设置列表项标记类型2.设置列表项标记图像3.设置列表项标记位置4.组合使用5.为不同列表项设置不同的样式6.重置列表样式 示例 介绍 在Web开发中&#xff0c;list-style 是CSS的一…

ORACLE 查询SQL优化

1 使用EXPLAIN PLAN 使用EXPLAIN PLAN查看查询的执行计划&#xff0c;这可以帮助你理解查询是如何被Oracle执行的。基于执行计划&#xff0c;你可以确定是否存在索引缺失、不必要的全表扫描等问题。 以下是几种使用EXPLAIN PLAN的方法&#xff1a; 使用EXPLAIN PLAN FOR: 你可以…

【Epoch,Batch,Iteration】深度学习模型训练相关基础概念光速理解!

&#x1f525;模型训练相关基础概念&#xff01; Epoch: 一次 epoch 代表整个训练数据集已经被完整地送入神经网络进行了一轮训练。通常&#xff0c;模型需要多次 epoch 才能充分学习数据集中的模式。Batch: 由于数据集可能过大&#xff0c;无法一次性全部加载到内存中进行训练…

解决VSCode右键没有Open In Default Browser问题

在VSCode进行Web小程序测试时&#xff0c;我们在新建的HTML文件中输入 !会自动生成页面代码骨架&#xff0c;写入内容后&#xff0c;我们想要右键在浏览器中预览。发现右键没有“Open In Default Browser”选项。原因是没有安装插件。 下面是解决方案&#xff1a;首先在VSCode找…

探索Lora:微调大型语言模型和扩散模型的低秩适配方法【原理解析,清晰简洁易懂!附代码】

探索Lora&#xff1a;微调大型语言模型和扩散模型的低秩适配方法 随着深度学习技术的快速发展&#xff0c;大型语言模型&#xff08;LLMs&#xff09;和扩散模型&#xff08;Diffusion Models&#xff09;在自然语言处理和计算机视觉领域取得了显著的成果。然而&#xff0c;这…

3d渲染的常用概念和技术,渲染100邀请码1a12

之前我们介绍了3D渲染的基本原理和流程&#xff0c;这次说下几个常用概念和技术。 3D渲染中涉及到很多专业的概念和技术&#xff0c;它们决定了渲染质量和效果&#xff0c;常用的有以下几个。1、光线追踪 光线追踪是一些专业渲染器&#xff08;如V-Ray和Corona等&#xff09;…

Android UI控件详细解析(四)

1.UI控件 1.1 TextView控件 常用属性 属性含义id给当前控件定义了一个唯 一标识符layout_width高度&#xff0c;单位&#xff1a;dp (wrap_content, match_parent)layout_height宽度&#xff0c;单位&#xff1a;dp (wrap_content, match_parent)background设置背景图片text…

Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld

文章目录 前言一、Django环境配置1、python 环境2、Django环境3、mysql环境4、IDE&#xff1a;pycharm 二、第一次创建Django项目1、创建项目door_web_django_system2、运行启动 三、Django项目介绍1、介绍Django项目结构2、第一个helloword4、django的项目逻辑&#xff08;和j…

React + Taro 项目 实际书写 感受

之前我总结了部分react 基础 根据官网的内容 以及Taro 框架的内容 今天我试着开始写了一下页面和开发 说一下我的感受 我之前写的是vue3 今天是第一次真正根据需求做页面开发 和逻辑功能 代码的书写 主体就是开发了这个页面 虽说这个页面 很简单 但是如果你要是第一次写 难说…

CATIA入门操作案例——压缩弹簧绘制,螺旋线的使用,法则曲线应用

目录 引出画压缩弹簧画等距部分画两端的压缩部分曲线缝合和扫掠封闭曲面得实体 总结异形弹簧新建几何体草图编辑&#xff0c;画一条样条线进行扫掠&#xff0c;圆心和半径画出曲面上的螺旋线再次选择扫掠&#xff0c;圆心和半径 其他自定义信号和槽1.自定义信号2.自定义槽3.建立…