浅谈泛型擦除

文章目录

    • 泛型擦除
      • (1)转换泛型表达式
      • (2)转换泛型方法
      • 泛型擦除带来的问题

泛型擦除

  在编码阶段使用泛型时加上的类型参数,会被编译器在编译阶段去掉,这个过程叫做泛型擦除。

  泛型主要用于编译阶段。在编译后生成的Java字节码文件中不包含泛型中的类型信息。例如,在编码时定义的List<Integer>List<String>经过编译后统一为List。JVM读取的只是List,由泛型附加的类型信息对JVM来说是不可见的。

Java核心技术卷I解释:

  无论何时定义一个泛型类型,都会自动提供一个相应的原始类型(raw type)。这个原始类型的名字就是去掉类型参数后的泛型类型名。类型变量会被擦除(erased),并替换为其限定类型(或者,对于无限定的变量则替换为Object)。

例如,

泛型类Pair<T>如下:

public class Pair<T>{private T first;private T second;public Pair(T first,T second){this.first=first;this.second=second;}public T getFirst(){return first;}public T getSecond(){return second;}public void setFirst(T newValue){first=newValue;}public void setSecond(T newValue){second=newValue;}
}

Pair<T>的原始类型如下所示:

public class Pair{private Object first;private Object second;public Pair(Object first,Object second){this.first=first;this.second=second;}public Object getFirst(){return first;}public Object getSecond(){return second;}public void setFirst(Object newValue){first=newValue;}public void setSecond(Object newValue){second=newValue;}
}

  因为T是一个无限定的变量,所以直接用Object替换。

  在程序中可以包含不同类型的Pair,例如Pair<String>Pair<LocalDate>。不过擦除类型后,它们都会编程原始的Pair类型。

  假定我们声明了泛型上限:

public class Interval<T extends Comparable&Serializable> implements Serializable{private T lower;private T upper;...public Interval(T first,T second){if(first.compareTo(second)<=0){lower=first;upper=second;}else{lower=second;upper=first;}}
}

  此时原始类型如下所示:

public class Interval implements Serializable{private Comparable lower;private Comparable upper;...public Interval(Comparable first,Comparable second){if(first.compareTo(second)<=0){lower=first;upper=second;}else{lower=second;upper=first;}}
}

  如果将限定切换为class Interval<T extends Serializable&Comparable>,原始类型会用Serializable替换T,而编译器在必要时要向Comparable插入强制类型转换。

(1)转换泛型表达式

  编写一个泛型方法调用时,如果擦出了返回类型,编译器会插入强制类型转换。例如:

Pair<Employee> buddies=...;
Employee buddy=buddies.getFirst();

  getFirst擦除类型后的返回类型是Object。编译器自动插入转换到Employee的强制类型转换。也就是说,编译器把这个方法调用转换为两条虚拟机指令:

  • 对原始方法Pair.getFirst的调用。
  • 将返回的Object类型强制转换为Employee类型。

  当访问一个泛型字段时,也要插入强制类型转换。假设Pair类的first字段和second字段都是公共的。表达式

Employee buddy=buddies.first;

  也会在结果字节码中插入强制类型转换。

(2)转换泛型方法

  类型擦除也会出现在泛型方法中。

public static <T extends Comparable> T min(T[] a)

  经过泛型擦除后,只剩下:

public static Comparable min(Comparable[] a);

  注意,类型参数T已经被擦出了,只留下了限定类型Comparable。

泛型擦除带来的问题

  当然,泛型擦除也带来了许多问题,这里就不细讲了,只是小总结下:

  • 不能用基本类型实例化类型参数
  • 运行时类型查询只适用于原始类型
  • 不能创建参数化类型的数组
  • 不能实例化类型变量
  • 不能构造泛型数组
  • 泛型类的静态上下文中类型变量无效
  • 不能抛出或捕获泛型类的实例
  • 可以取消对检查型异常的检查
  • 注意擦除后的冲突

参考:
《剑指Java》
《Java核心技术卷I》
泛型详解
泛型之类型擦除

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot 可以同时处理多少请求

一、前言 首先&#xff0c;在Spring Boot应用中&#xff0c;我们可以使用 Tomcat、Jetty、Undertow 等嵌入式 Web 服务器作为应用程序的运行容器。这些服务器都支持并发请求处理的能力。另外&#xff0c;Spring Boot 还提供了一些配置参数&#xff0c;可以对 Web 服务器进行调…

北大硕士7年嵌入式学习经验分享

阶段 1 大一到大三这个阶段我与大多数学生相同&#xff1a; 学习本专业知识&#xff08;EE专业&#xff09;&#xff0c;学习嵌入式软件开发需要的计算机课程&#xff08;汇编原理&#xff0c;计算机组成原理&#xff0c;操作系统&#xff0c;C语言等&#xff09;&#xff0c…

常见web信息泄露

一、源码(备份文件)泄露 1、git泄露 Git是一个开源的分布式版本控制系统&#xff0c;在执行git init初始化目录的时候&#xff0c;会在当前目录下自动创建一个.git目录&#xff0c;用来记录代码的变更记录等。发布代码的时候&#xff0c;如果没有把.git这个目录删除&#xff…

SpringBoot 中使用JPA

最近忙里偷闲&#xff0c;想写一点关于JPA的东西&#xff0c;另外也加深下对JPA的理解&#xff0c;才有了此篇博文。 一、JPA JPA &#xff08;Java Persistence API&#xff09;Java持久化API&#xff0c;是一套Sun公司Java官方制定的ORM 规范&#xff08;sun公司并没有实现…

mfc140u.dll是什么文件?mfc140u放在哪个文件夹?详细修复教程

今天我想和大家分享一个非常常见的问题——mfc140u.dll丢失的困扰以及解决方法。 首先&#xff0c;让我们来了解一下什么是mfc140u.dll。这是一个非常重要的动态链接库文件&#xff0c;它是Microsoft Foundation Class Library的一个组件。许多软件和游戏都需要这个文件的支持才…

github搜索技巧

指定语言 language:java 比如我要找用java写的含有blog的内容 搜索项目名称包含关键词的内容 vue in:name 其他如项目描述跟项目文档&#xff0c;如下 组合使用 vue in:name,description,readme 根据Star 或者fork的数量来查找 总结 springboot vue stars:>1000 p…

(三)激光线扫描-中心线提取

光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素。 1. 光条的高斯分布 激光线条和打手电筒一样,中间最亮,越像周围延申,光强越弱,这个规则符合高斯分布,如下图。 2. 传统光条纹中心提取算法 传统的光条纹中心提取算法有 灰度重心法、…

漏洞扫描环境:win10系统用VMware Workstation打开虚拟机若干问题

win10系统用VMware Workstation打开虚拟机若干问题 一 .VMware打开虚拟机就蓝屏重启怎么解决&#xff1f;一. VMware打开虚拟机就蓝屏重启怎么解决&#xff1f;方法一&#xff1a;1、同时按下CTRLSHIFTESC打开任务管理器功能&#xff0c;之后依次点击-详细信息-性能后出现下列界…

苹果双系统和虚拟机哪个好用?

苹果不能直接使用windows系统中的软件&#xff0c;但windows系统较为全面&#xff0c;为了解决苹果电脑不能使用windows系统软件的问题&#xff0c;使用双系统和类虚拟机是非常不错的解决方案。那么&#xff0c;苹果双系统和虚拟机哪个好&#xff1f;这两种解决方案各有千秋。苹…

ubuntu18.04 OpenGL开发(显示YUV)

源码参考&#xff1a;https://download.csdn.net/download/weixin_55163060/88382816 安装opengl库 sudo apt install libglu1-mesa-dev freeglut3-dev mesa-common-dev 安装opengl工具包 sudo apt install mesa-utils 检查opengl版本信息&#xff08;桌面终端执行&#xff09…

ubuntu 18.04 LTS安装opencv 3.4.16 + opencv_contrib 3.4.16

1.下载 opencv 3.4.16 opencv_contrib 3.4.16 其中&#xff0c;opencv_contrib解压后的多个文件夹复制到opencv内、合并 2.安装 参考博文&#xff1a; https://zhuanlan.zhihu.com/p/650792342 https://zhuanlan.zhihu.com/p/87197806 其中 &#xff08;1&#xff09;cmake前…

【AI视野·今日Sound 声学论文速览 第十七期】Tue, 3 Oct 2023

AI视野今日CS.Sound 声学论文速览 Tue, 3 Oct 2023 Totally 15 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers DiffAR: Denoising Diffusion Autoregressive Model for Raw Speech Waveform Generation Authors Roi Benita, Michael Elad, Joseph Kes…

大数据-玩转数据-Flink 海量数据实时去重

一、海量数据实时去重说明 借助redis的Set&#xff0c;需要频繁连接Redis&#xff0c;如果数据量过大, 对redis的内存也是一种压力&#xff1b;使用Flink的MapState&#xff0c;如果数据量过大, 状态后端最好选择 RocksDBStateBackend&#xff1b; 使用布隆过滤器&#xff0c;…

结构型设计模式——桥接模式

摘要 桥接模式(Bridge pattern): 使用桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。 一、桥接模式的意图 将抽象与实现分离开来&#xff0c;使它们可以独立变化。 二、桥接模式的类图 Abstraction: 定义抽象类的接口Implementor: 定义实现类接口 …

【Pytorch笔记】4.梯度计算

深度之眼官方账号 - 01-04-mp4-计算图与动态图机制 前置知识&#xff1a;计算图 可以参考我的笔记&#xff1a; 【学习笔记】计算机视觉与深度学习(2.全连接神经网络) 计算图 以这棵计算图为例。这个计算图中&#xff0c;叶子节点为x和w。 import torchw torch.tensor([1.]…

使用关键字interface来声明使用接口-PHP8知识详解

继承特性简化了对象、类的创建&#xff0c;增加了代码的可重用性。但是php8只支持单继承&#xff0c;如果想实现多继承&#xff0c;就需要使用接口。PHP8可以实现多个接口。 接口类通过关键字interface来声明&#xff0c;接口中不能声明变量&#xff0c;只能使用关键字const声明…

机器人中的数值优化|【六】线性共轭梯度法,牛顿共轭梯度法

机器人中的数值优化|【六】线性共轭梯度法&#xff0c;牛顿共轭梯度法 往期回顾 机器人中的数值优化|【一】数值优化基础 机器人中的数值优化|【二】最速下降法&#xff0c;可行牛顿法的python实现&#xff0c;以Rosenbrock function为例 机器人中的数值优化|【三】无约束优化…

stm32 - 中断

stm32 - 中断 概念中断向量表NVIC 嵌套中断向量控制器优先级 中断EXTI概念基本结构例子- 对射式红外传感器计次例子 - 旋转编码器 概念 stm32 支持的中断资源&#xff08;都属于外设&#xff09; EXTITIMADCUSARtSPII2C stm32支持的中断 内核中断 外设中断 中断通道与优先级 一…

C# 读取Execl文件3种方法

方法 1&#xff0c;使用OLEDB可以对excel文件进行读取 1.1C#提供的数据连接有哪些 对于不同的.net数据提供者&#xff0c;ADO.NET采用不同的Connection对象连接数据库。这些Connection对我们屏蔽了具体的实现细节&#xff0c;并提供了一种统一的实现方法。 Connection类有四…

【Linux】线程池

目录 一、线程池1.什么是线程池2.线程池图解3.实现代码 二、单例模式1.单例模式的概念2.饿汉方式实现单例模式3.懒汉方式实现单例模式4.懒汉方式实现单例模式的线程池 一、线程池 1.什么是线程池 线程虽然比进程轻量了很多&#xff0c;但是每创建一个线程时&#xff0c;需要向…