Java 泛型相关知识

什么是泛型?

Java 泛型(generics)是JDK5中引入的一种参数化类型特性。

为什么使用泛型,使用泛型的好处?

  1. 代码更健壮(只要编译期没有警告,那么运行期就不会出现 ClassCastException)
  2. 代码更简洁(不用强转)
  3. 代码更灵活,复用

什么是参数化类型:

  • 把类型当参数一样传递
  • <数据类型> 只能是引用类型(泛型的副作用)

举个例子:

public interface Plate<T> {public void set(T t);public T get();
}
public class ATPlate<T> implements Plate<T> {private List<T> items = new ArrayList<T>(10);public <T> ATPlate<T> getATPlate() {return new ATPlate<T>();}
}
  • Plate<T> 中的 "T” 称为类型参数,Plate<T> 整个称为泛型类型
  • Plate<Banana> 中的 “Banana” 称为实际类型参数, Plate<Banana> 整个称为参数化的类型ParameterizedType

泛型其实就是在类上面传参,可以类比方法传参,只不过类上面传的参数类型也只能是类。

泛型类型可以通过extends指定多个限定类型。

什么是多个限定类型,例如:

class A {}
interface B {}
interface C {}// 具有多个限定的类型变量是范围中列出的所有类型的子类型。如果范围之一是类,则必须首先声明类
class D<T extends B & A & C> {} // 编译报错
class D<T extends A & B & C> {} // 编译OK

泛型擦除

Q:Java 泛型的原理?什么是泛型擦除机制?

  • Java 的泛型是 JDK5 引入的特性,为了向下兼容,虚拟机其实是不支持泛型,所以 Java 实现的是一种伪泛型机制,也就是说 Java 在编译期擦除了所有的泛型信息,这样 Java 就不需要产生新的类型到字节码所有的泛型类型最终都是一种原始类型在 Java 运行时根本就不存在泛型信息。

Q:Java 编译器具体是如何擦除泛型的?

  1. 检查泛型类型,获取目标类型
  2. 擦除类型变量,并替换为限定类型
    • 如果泛型类型的类型变量没有限定(<T>),则Object作为原始类型
    • 如果有限定(<T extends XCIass>),则XCIass作为原始类型
    • 如果有多个限定(T extends XCIass1 & XCIass2),则使用第一个边界XCIass1作为原始类型
  3. 在必要时插入类型转换以保持类型安全
  4. 生成桥方法以在扩展时保持多态性

例如,只有一个泛型 T 擦除后只有一个 Object 对象:

在这里插入图片描述

如果泛型有多个继承限定类型,则使用第一个限定类作为擦除后的类型,此外如果泛型类继承了支持泛型的接口,还会生成桥方法

在这里插入图片描述

如何通过反射获取泛型参数

泛型虽然被擦除了,但是在 类常量池 里面其实保留了泛型信息,所以可以通过反射获取泛型的信息 getGenericType()

Java 的泛型擦除并不是将所有泛型信息全部都擦除了,会将类上和方法上声明的泛型信息保存在字节码中的 Signature 属性中,这也是反射能够获取泛型的原因。但是在方法中的泛型信息是完全擦除了。

public class HelloWorld {Map<String, String> map;public static void main(String[] args){ try {Field field = HelloWorld.class.getDeclaredField("map"); Type type = field.getGenericType();System.out.println(type);// java.util.Map<java.lang.String, java.lang.String>System.out.println(type instanceof ParameterizedType); // trueParameterizedType pType = (ParameterizedType) type;System.out.print1n(pType.getRawType());// interface java.util.Map for (Type argType : pType.getActualTypeArguments()) {System.out.println(argType); // class java.lang.String }System.out.println(pType.getOwnerType()); // nullMethod method =HelloWorld.class.getMethod("applyMethod",Map.Entry.class); 

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

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

相关文章

React基础语法整理

安装&#xff1a; yarn create react-app reatc-lesson --template typescript yarn create 创建一个react-app的应用 项目名称 typescript 的模板react-app 官方地址 https://create-react-app.bootcss.com/docs/adding-typescriptreact 语法文档 https://zh-hans.react.dev…

基于Vue框架的电子商城购物平台小程序的设计与开发

基于JavaWebSSMVue电子商城购物平台小程序系统的设计和实现 源码获取入口KaiTi 报告/Ren务书Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 KaiTi 报告/Ren务书 一、选题的目的和意义 自从微信推出了微信小程序…

使用命令行移除VSAN中故障磁盘

原创作者&#xff1a;运维工程师 谢晋 使用命令行移除VSAN中故障磁盘 前提故障盘移除 前提 客户有套VSAN环境内有一台服务器的磁盘组出现了一块故障的数据盘&#xff0c;但该盘已经处于完全掉线状态&#xff0c;无法进行正常移除。如下图&#xff1a; 如果遇到这种情况&am…

P9 LinuxC 进程概述 终端启动的程序父进程是终端

前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类&#xff09;_ChenPi的博客-CSDN博客》✨✨✨ &#x1f6f8;推荐专栏3: ​​​​​​《链表_ChenP…

【1】一文读懂PyQt简介和环境搭建

目录 1. PyQt简介 1.1. Qt 1.2. PyQt 1.3. 关于PyQt和PySide 2. 通过pip安装PyQt5 3. 无法运行处理 4. VSCode配置PYQT插件 PyQt官网:Riverbank Computing | Introduction 1. PyQt简介 PyQt是一套Python的GUI开发框架,即图形用户界面开发框架。 Python中经常使用的GU…

FreeRTOS的内存管理方法(超详细)

内存管理 我们知道每次创建任务、队列、互斥锁、软件定时器、信号量或事件组时&#xff0c;RTOS 内核都需要 RAM &#xff0c; RAM 可以从 RTOS API 对象创建函数内的 RTOS 堆自动动态分配&#xff0c; 或者由应用程序编写者提供。 如果 RTOS 对象是动态创建的&#xff0c;那么…

Leetcode—2646.最小化旅行的价格总和【困难】

2023每日刷题&#xff08;五十三&#xff09; Leetcode—2646.最小化旅行的价格总和 算法思想 看灵神的 实现代码 class Solution { public:int minimumTotalPrice(int n, vector<vector<int>>& edges, vector<int>& price, vector<vector&l…

发现数学之美--微积分的起源和用途(一文搞懂微积分)

数学&#xff0c;改变世界的基石。微积分十九世纪的三大自然发现之一&#xff0c;迪卡尔建立了解析几何&#xff0c;把数与图结合在一起&#xff0c;微积分的发现与创立&#xff0c;是数学新的里程碑&#xff0c;解决了常规方法无法解决的问题&#xff0c;是一次伟大的革命。迪…

git安装和配置

git安装和配置 一、软件介绍 Git是一个免费开源的分布式版本控制系统&#xff0c;旨在快速高效地处理从小型到大型项目的所有内容。 Git易于学习&#xff0c;占地面积小&#xff0c;性能闪电般快。它以廉价的本地分支、方便的暂存区域和多个工作流等功能胜过了Subversion、C…

【论文阅读】Reachability and distance queries via 2-hop labels

Cohen E, Halperin E, Kaplan H, et al. Reachability and distance queries via 2-hop labels[J]. SIAM Journal on Computing, 2003, 32(5): 1338-1355. Abstract 图中的可达性和距离查询是许多应用的基础&#xff0c;从地理导航系统到互联网路由。其中一些应用程序涉及到巨…

金南瓜SECS/GEM C# SDK 快速使用指南

本文对如何使用金南瓜SECS/GEM C# SDK 快速创建一个满足SECS/GEM通信要求的应用程序&#xff0c;只需简单3步完成。 第一步&#xff1a;创建C# .NET程序 示例使用Visual Studio 2010&#xff0c;使用者可以选择更高级版本 Visual Studio 第二步&#xff1a;添加DLL库引用&am…

图论-并查集

并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图,求最小生成树Kruskal算法和最近公共祖先(LCA)等. 并查集的基本操作主要有: .1.初始化 2.查询find 3.合并union 一般我们都会采用路径压缩 这样…

git标签的管理与思考

git 标签管理 git 如何打标签呢&#xff1f; 标签是什么? 标签 相当于一个 版本管理的一个贴纸&#xff0c;随时 可以通过标签 切换到 这个版本的状态 &#xff0c; 有人可能有疑问 git commit 就可以知道 代码的改动了&#xff0c; 为啥还需要标签来管理呢&#xff1f; …

node笔记

文章目录 一、Node.js基础1. 认识Node.js01 nodejs的特性02 使用 Node.js 需要了解多少 JavaScript03 浏览器环境vs node环境 2. 开发环境搭建3. 模块、包、commonJS02 CommonJS规范03 modules模块化规范写法 4. Npm&Yarn01 npm的使用02 全局安装 nrm03 yarn使用 5. 内置模…

在idea中使用maven创建dynamic web project

1、先创建一个empty project 2、添加一个module , 核心是选择maven archetype webapp, 这个是maven提供的创建web工程的模版。 3、添加完等自动安装好即可 4、目录可能不完整 右键src---->点击New---->点击Directory &#xff08;注意&#xff1a;这是笔者所缺失的结…

每日一道c语言

任务描述 题目描述:输入10个互不相同的整数并保存在数组中&#xff0c;找到该最大元素并删除它&#xff0c;输出删除后的数组 相关知识&#xff08;略&#xff09; 编程要求 请仔细阅读右侧代码&#xff0c;结合相关知识&#xff0c;在Begin-End区域内进行代码补充&#xf…

ooTD I 女儿是自己的,尽情打扮尽情可爱

分享女宝的时尚穿搭 奶乎乎的黄色也太好看了 超足充绒量&#xff0b;优质面料 柔软蓬松上身体验感超赞 怎么穿都好看系列 轻轻松松打造时尚造型&#xff01;&#xff01;

Linux 删除文件名乱码的文件

现象&#xff1a; 处理&#xff1a; 1.>ls -li 获取文件对应的ID号 2.把删除指定文件&#xff08;ID号 &#xff09;执行&#xff1a; find ./ -inum 268648910 -exec rm {} \;

微信小程序_介绍

开发准备 注册微信小程序 进入微信公众平台 点击立即注册&#xff0c;选择小程序&#xff0c;前往注册 完善个人/企业信息 获取AppID 进入小程序页面->开发->开发设置->AppID 下载微信开发者工具 微信官方下载下载微信开发者工具稳定版 创建项目 绑定AppID不使用…

用Rust刷LeetCode之27 移除元素

27. 移除元素 难度: 简单 原描述: 新描述: func removeElement(nums []int, val int) int { for i : 0; i < len(nums); i { if nums[i] val { nums append(nums[:i], nums[i1:]...) i-- } } return len(nums)} Rust 版本 下面这种写法编译无法通过: pub fn remove_…