【泛型】学习笔记

news/2024/9/11 3:27:02/ 标签: 学习, 笔记

1.工作中使用反射去创建对象

例子1@Getterprivate int type;private Class<? extends AbstractActivity> clazz;ActivityType(int type, Class<? extends AbstractActivity> clazz) {this.type = type;this.clazz = clazz;}public AbstractActivity newInstance(ActivityEntity activityEntity) {try {// 创建一个对象,并且传入一个参数return clazz.getConstructor(ActivityEntity.class).newInstance(activityEntity);} catch (Exception e) {logger.error("ActivityType newInstance catch error:", e);return null;}}

2.反射+泛型创建对象的例子

step1.声明泛型方法和反射去创建对象的代码:public static <T> T f(Class<T> clazz, int num) throws Exception {// 使用时,我们要知道调用的类型是啥,进行指定即可,int.class其实我们可以用限定符指定return clazz.getConstructor(int.class).newInstance(num);}step2.使用 // 通过指定类型参数+传入参数Integer num = f(int.class, 3);System.out.println(num);

3.guava TypeToken // 解决类型擦除

Guava的TypeToken在泛型编程中的应用_guava typetoken-CSDN博客

4.Fastjson中TypeTolen的使用 // 指定TypeToken保证解析出的类型为指定的,而不是Object

public static void main(String ... args) {String personString = "[{\"id\":1,\"name\":\"Irene\",\"password\":\"123456\"},{\"id\":2,\"name\":\"Aiden\","+ "\"password\":\"123456\"}]";List<Person> persons = JSON.parseObject(personString, new TypeToken<List<Person>>(){}.getType());}@Datapublic static class Person {private int id;private String name;private String password;}

5.黑马学习笔记

/*
1)没有泛型时:没有泛型前: 使用Object可以存放任意的元素泛型的出现:和集合有很大的关系需要强转使用上:读取时是Object,具体使用需要强转。严重问题:虽然类型转换有错误,但是编译期没问题,运行期异常。2)引入泛型作用:编译器的检查。 在使用时必须按照指定的类型来存储。3)泛型的好处:1.编译期检查类型2.无需数据类型转换4)会自动装箱(添加时)。会自动拆箱(从集合取出数据时)。5)泛型集合有点像:类型的形参。6)泛型的本质:就是参数化类型。类型的形参。7)泛型标识: T,E,K,V8)泛型类没有指定类型,则按照Object。9)泛型类,不支持int,编译期的时候,转化为Object,因为int不继承Object,因此不能是基本数据类型!10)打印xx.getClass():同一个泛型类,根据不同的数据类型创建的对象,本质是同一类型。11)泛型在逻辑上可以看成是不同的类型,但是实际上都是相同的类型,也就是Xxx.class12)泛型类继承:子类有泛型的话,必须有一个类型和父类提供的一样,当然自己可以新增别的泛型类型。子类无泛型的话,则必须明确父类的泛型类型。13)泛型接口实现类不是泛型类实现类是泛型类14)泛型方法泛型方法:在调用方法的时候,指明泛型的具体类型。注意:只使用了泛型类中的类型的方法不是泛型方法,而是成员方法。泛型方法是独立于泛型类中的类型的,可以加static。 成员方法类型使用的是类中指定的泛型,不能加static。泛型类则是:在实例化的时候指明泛型的具体类型。15)类型通配符上限:? : 表示实参,但是我们可以指定边界,比如: <? extends Number>, 就是:Number或者Number的子类。问题: 不能填充元素。因为我们不知道它到底是什么类型,所以我们不能new一个元素填充进去。下限:<? super 实参类型>16)泛型擦除:1.5版本才引入的,之前没有泛型,为了和之前代码兼容,泛型只存在于编译阶段,在进入jvm之前,与泛型相关的信息会被擦除掉。证明:intList.getClass().getSimpleName();strList.getClass().getSimpleName();打印信息:发现都是ArrayList17)拿到字节码文件Class<? extends Erasure> clazz = erasure.getClass();获取到所有的成员变量:Field[] fields : clazz.getDeclaredFields();field.getType().getSimpleName() 发现 是Object // 也就是通过反射再去看的时候,类型被擦除成了Object有限制的类型擦除:T extens Number,就会被擦除为Number桥接方法的生成:类型擦除和多态发生了冲突,为了解决这个问题,编译器会产生一个桥接方法,在虚拟机中会由参数好返回值类型不同而产生2个不同的字节码文件,但是虚拟机能够正确的处理这种情况。info:Integerinfo:Object18)泛型数组可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象。可以通过:Array.newInstance(Class<T>, int)创建T[]数组在编译期会进行类型擦除,而数组则是一直持有,所以2者设计是冲突的,java这直接不让那么做。创建:T[] arr = new T[3]; // 直接失败,因为我们根本不知道T是什么类型。@SuppressWarnings("all")public static <T> T[] createArr(Class<T> clazz, int len) {return (T[]) Array.newInstance(clazz, len);}19)泛型和反射Class<Person> personClass = Person.class;Constructor<Person> constructor = personClass.getConstructor();Person person = constructor.newInstance();*/

6.桥接方法

在某些情况下,基本类型擦除会导致方法重写的问题,为了防止出现这种情况,Java编译器有时会生成桥接方法。问题来了,什么是桥接方法?

public interface Parent<T> {public void set(T t);
}

接着定义一个类实现Parent类,并指向泛型类型为String

public class Child implements Parent<String> {@Overridepublic void set(String s) {System.out.println("child");}
}


在上面的代码中,Child中的set方法实现并重写了Parent中的set方法
到那时,泛型在编译之后就会被类型擦除,Parent中的set(T t)会被擦除编程set(Object t),这与Child中的set(String s) 方法具有不同的参数类型,那么就不是方法重写,而是方法重载了。
问题来了,Child类实现了Parent接口,但是并没有实现其中的set(Object t)方法,这是怎么回是?
其实,这个问题在泛型设计之初就被考虑到了,编译器通过Child类中插入一个桥接方法set(Object t) 来解决这个问题,
我们把Child编译成class文件,再使用jad工具反编译成Java文件,得到如下内容

public class Childimplements Parent
{public Child(){}public void set(String s){System.out.println("child");}public volatile void set(Object obj){set((String)obj);}
}


在Child类中,JVM自动帮我们生成了一个set(Object obj)方法,并且调用了set(String s) 方法,这个set(Object obj)方法就是桥接方法
所以当一个字类在继承(或实现)一个父类(或接口)的泛型方法时,在字类中明确指定了泛型类型,编译器为了让字类有一个与父类的方法签名一致的方法,就会在子类中自动生成一个与父类的方法签名一致的桥接方法


http://www.ppmy.cn/news/1475281.html

相关文章

Spark底层原理:案例解析(第34天)

系列文章目录 一、Spark架构设计概述 二、Spark核心组件 三、Spark架构设计举例分析 四、Job调度流程详解 五、Spark交互流程详解 文章目录 系列文章目录前言一、Spark架构设计概述1. 集群资源管理器&#xff08;Cluster Manager&#xff09;2. 工作节点&#xff08;Worker No…

RabbitMQ中常用的三种交换机【Fanout、Direct、Topic】

目录 1、引入 2、Fanout交换机 案例&#xff1a;利用SpringAMQP演示Fanout交换机的使用 3、Direct交换机 案例&#xff1a;利用SpringAMQP演示Direct交换机的使用 4、Topic交换机 案例&#xff1a;利用SpringAMQP演示Topic交换机的使用 1、引入 真实的生产环境都会经过e…

mysql之导入测试数据

运维时经常要这样&#xff1a;mysql改表名&#xff0c;创建一个一样的表不含数据&#xff0c;复制旧表几条数据进去 改变表的名字&#xff1a; RENAME TABLE old_table_name TO new_table_name; 这将把原来的表old_table_name重命名为new_table_name。 创建一个一样的表结构…

MES实时监控食品加工过程中各环节的安全

在实时监控食品加工过程中各环节的安全风险方面&#xff0c;万界星空科技的MES&#xff08;制造执行系统&#xff09;解决方案发挥了至关重要的作用。以下是具体如何通过MES系统实现实时监控食品加工过程中各环节安全风险的详细阐述&#xff1a; 一、集成传感器与实时监控 MES…

1.1 - Android启动概览

第一章 系统启动流程分析 第一节 Android启动概览 Android启动概览可以从多个方面进行描述&#xff0c;包括启动流程、关键组件及其作用等。以下是一个详细的Android启动概览&#xff1a; 一、启动流程 Android设备的启动流程大致可以分为以下几个阶段&#xff1a; 上电与引导…

数据结构实操代码题~考研

作者主页: 知孤云出岫 目录 数据结构实操代码题题目一&#xff1a;实现栈&#xff08;Stack&#xff09;题目二&#xff1a;实现队列&#xff08;Queue&#xff09;题目三&#xff1a;实现二叉搜索树&#xff08;BST&#xff09;题目四&#xff1a;实现链表&#xff08;Linked…

虚幻引擎ue5如何调节物体锚点

当发现锚点不在物体上时&#xff0c;如何调节瞄点在物体上。 步骤1&#xff1a;按住鼠标中键拖动锚点&#xff0c;在透视图中多次调节锚点位置。 步骤2:在物体上点击鼠标右键点击-》锚定--》“设置为枢轴偏移”即可。

2974.最小数字游戏

1.题目描述 你有一个下标从 0 开始、长度为 偶数 的整数数组 nums &#xff0c;同时还有一个空数组 arr 。Alice 和 Bob 决定玩一个游戏&#xff0c;游戏中每一轮 Alice 和 Bob 都会各自执行一次操作。游戏规则如下&#xff1a; 每一轮&#xff0c;Alice 先从 nums 中移除一个 …

机器学习扫盲:优化算法、损失函数、评估指标、激活函数、网络架构

专栏介绍 1.专栏面向零基础或基础较差的机器学习入门的读者朋友,旨在利用实际代码案例和通俗化文字说明,使读者朋友快速上手机器学习及其相关知识体系。 2.专栏内容上包括数据采集、数据读写、数据预处理、分类\回归\聚类算法、可视化等技术。 3.需要强调的是,专栏仅介绍主…

MySQL8之mysql-community-server-debug的作用

mysql-community-server-debug是MySQL社区服务器的一个调试版本&#xff0c;它主要用于开发和调试MySQL数据库服务器。与标准的MySQL社区服务器版本相比&#xff0c;调试版本包含了额外的调试信息和工具&#xff0c;以帮助开发人员和数据库管理员诊断和解决MySQL服务器中的问题…

npm发布的包如何快速在cnpm上使用

npm发布的包如何快速在cnpm上使用 解决方案 前往淘宝npm镜像官网 搜索插件库并点击同步 等待一分钟即可查看最新版本

9.5 栅格图层符号化多波段彩色渲染

文章目录 前言多波段彩色渲染QGis设置为多波段彩色二次开发代码实现多波段彩色 总结 前言 介绍栅格图层数据渲染之多波段彩色渲染说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 多波段彩色渲染 以“3420C_2010_327_RGB_LATLNG.tif”数据为例&#xff0c…

等保测评新趋势:应对数字化转型中的安全挑战

随着信息技术的飞速发展&#xff0c;数字化转型已成为企业提升竞争力、优化运营效率的重要手段。然而&#xff0c;这一转型过程中&#xff0c;企业也面临着前所未有的安全挑战。等保测评&#xff08;信息安全等级保护测评&#xff09;作为保障信息系统安全的重要手段&#xff0…

Python爬虫教程第5篇-使用BeautifulSoup查找html元素几种常用方法

文章目录 简介find()和find_all()字符串通过id查找通过属性查找通过.方式查找通过CSS选择器查找通过xpath查找正则表达自定义方法总结 简介 上一篇详细的介绍了如何使用Beautiful Soup的使用方法&#xff0c;但是最常用的还是如何解析html元素&#xff0c;这里再汇总介绍下查询…

C# modbus验证

窗体 还有添加的serialPort控件串口通信 设置程序配置 namespace CRC {public static class CRC16{/// <summary>/// CRC校验&#xff0c;参数data为byte数组/// </summary>/// <param name"data">校验数据&#xff0c;字节数组</param>///…

SpringBoot新手快速入门系列教程十一:基于Docker Compose部署一个最简单分布式服务项目

我的教程都是亲自测试可行才发布的&#xff0c;如果有任何问题欢迎留言或者来群里我每天都会解答。 如果您还对于Docker或者Docker Compose不甚了解&#xff0c;可以劳烦移步到我之前的教程&#xff1a; SpringBoot新手快速入门系列教程九&#xff1a;基于docker容器&#xff…

ZGC的流程图

GC标记过程 1、初始标记 扫描所有线程栈的根节点&#xff0c;然后再扫描根节点直接引用的对象并进行标记。这个阶段需要停顿所有的应用线程&#xff08;STW&#xff09;&#xff0c;但由于只扫描根对象直接引用的对象&#xff0c;所以停顿时间很短。停顿时间高度依赖根节点的数…

14-47 剑和诗人21 - 2024年如何打造AI创业公司

​​​​​ 2024 年&#xff0c;随着人工智能继续快速发展并融入几乎所有行业&#xff0c;创建一家人工智能初创公司将带来巨大的机遇。然而&#xff0c;在吸引资金、招聘人才、开发专有技术以及将产品推向市场方面&#xff0c;人工智能初创公司也面临着相当大的挑战。 让我来…

LDAPWordlistHarvester:基于LDAP数据的字典生成工具

关于LDAPWordlistHarvester LDAPWordlistHarvester是一款功能强大的字典列表生成工具&#xff0c;该工具可以根据LDAP中的详细信息生成字典列表文件&#xff0c;广大研究人员随后可以利用生成的字典文件测试目标域账号的非随机密码安全性。 工具特征 1、支持根据LDAP中的详细信…

利用宝塔安装一套linux开发环境

更新yum&#xff0c;并且更换阿里镜像源 删除yum文件 cd /etc/yum.repos.d/ 进入yum核心目录 ls sun.repo rm -rf * 删除之前配置的本地源 ls 配置阿里镜像源 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 配置扩展包 wge…