最近看了《thinking in java》的第十五章泛型,感觉有些东西需要记录下来。

泛型是Java SE5才被引入的概念,现在我的工作中泛型主要使用在集合,这样可以知道set()和get()的类型(类型检查是在编译阶段,可以使用反射绕过编译),而不必再进行额外的转型操作。

今天,我们主要是来聊一聊Java泛型的擦除。

或许,你对Java泛型的擦除的概念不是很理解,下面我们来看一个例子:

很多人会认为ArrayList<String>和ArrayList<Integer>是不同的类型,但是这段程序打印的结果是true。

下面我们再来看一个例子:

这种代码在Java中是不能编译通过的,即使我传的是baby这个类的对象。但是这种代码在C++中不仅能编译通过还能执行。

这种在泛型代码内部获取不到有关泛型参数类型的一种泛型实现并不是Java的语言特性,而是Java泛型实现的一种折中。

Java的泛型是使用擦除实现的。这也就意味着当你在使用泛型的时候,任何具体的类型信息都被擦除了,你唯一知道的是你在使用一个对象。就如同上例的ArrayList<String>和ArrayList<Integer>在运行是相同的类型,它们都被擦出成它们的原生类型,List。

如果,泛型在Java 1.0中就已经是其中一部分,那么这个特性很可能就不会有擦除来实现,将会使用具体化,使类型参数保持一致,因此就可以在类型参数上执行基于类型语言的操作和反射操作。

同样,擦除的代价也是巨大的。泛型不能用于显式的引用运行时类型的操作之中,例如转型,instanceof和new。

即使,擦除在方法体内移除了有关实际类型的信息,编译器仍能够确保在方法或者类中使用的类型的内部一致性。以为擦除在方法体内移除了类型信息,所以运行时的问题的就是边界:对象进入和离开的方法的地点。这些就是编译器在编译期执行类型检查并插入转型代码的地点。下面的例子很好的说明了这点。

下面是用Javap  -c Test反编译这个类看到的内容

set()和get()方法将直接存储和产生值,转型是在调用get()的时候接受检查的。

下面我们用上泛型再看看,

反编译的内容如下:

所产生的字节码相同,对进入set()的类型检查是不需要的,因为这由编辑器执行。而对从get()返回的值仍需进行转型。

所以在泛型中的所有动作都发生在边界处。

聊一聊Java泛型的擦除的更多相关文章

  1. java泛型-类型擦除

    详细内容:参考java编程思想P373,p650. Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就 ...

  2. 【转】聊一聊-JAVA 泛型中的通配符 T,E,K,V,?

    原文:https://juejin.im/post/5d5789d26fb9a06ad0056bd9 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型 ...

  3. 关于Java泛型"擦除"的一点思考

    头次写博客,想说的东西不难,关于泛型的疑问,是前一阵在学习jackson中遇到的. 下面就把我所想到的.遇到的,分享出来. 泛型是JDK1.5后的一个特性,是一个参数类型的应用,可以将这个参数声明在类 ...

  4. 【Java心得总结三】Java泛型上——初识泛型

    一.函数参数与泛型比较 泛型(generics),从字面的意思理解就是泛化的类型,即参数化类型.泛型的作用是什么,这里与函数参数做一个比较: 无参数的函数: public int[] newIntAr ...

  5. 【Java心得总结四】Java泛型下——万恶的擦除

    一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...

  6. Java泛型-内部原理: 类型擦除以及类型擦除带来的问题

    一:Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除.Java的泛型基本上都是在编译 ...

  7. Java泛型-类型擦除

    一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变 ...

  8. Java泛型:类型擦除

    类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String& ...

  9. java泛型 8 泛型的内部原理:类型擦除以及类型擦除带来的问题

    参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...

随机推荐

  1. 解题报告 『[USACO08NOV]Mixed Up Cows(状压动规)』

    原题地址 观察数据范围:4 ≤ N ≤ 16. 很明显,这是一道状压DP. 定义:dp[i][j]表示队尾为奶牛i,当前含奶牛的状态为j,共有多少组符合条件的队伍. 代码实现如下: #include ...

  2. [cf1025D][区间dp]

    http://codeforces.com/contest/1025/problem/D D. Recovering BST time limit per test 1 second memory l ...

  3. [IOS][已越狱]配合网易云音乐,使用Bridge快速免iTunes导入音乐到“音乐”

    前置:已越狱IOS设备   工具表: Bridge{bigboss源,可以使用cydown以非官方服务器下载安装} 网易云音乐{Appstore} Filza{很多源都有}     网易云试听缓存路径 ...

  4. linux下突破10万高并发的nginx性能优化经验

    一.这里的优化主要是指对nginx的配置优化,一般来说nginx配置文件中对优化比较有作用的主要有以下几项:1)nginx进程数,建议按照cpu数目来指定,一般跟cpu核数相同或为它的倍数.worke ...

  5. python之计算机硬件基本认知_数据单位_进制间转换_数的原码反码补码

    一:计算机硬件基本认知 cpu:   中央处理器.   相当于人的大脑.运算中心,控制中心. 内存:  临时存储数据. 优点:读取速度快,缺点:容量小,造价高,断电即消失. 硬盘:  长期存储数据. ...

  6. logback root level logger level 日志级别覆盖?继承?

    1. logback-spring.xml 配置 <appender name="STDOUT" class="ch.qos.logback.core.Consol ...

  7. [转载]使用QTP测试Windows对象

    Desktop对象的使用: 通过Desktop对象,可以访问Windows的桌面顶层对象.Desktop对象包括CaptureBitmap.ChildObjects.RunAnalog方法. (1)  ...

  8. FPGA Asynchronous FIFO设计思路

    FPGA Asynchronous FIFO设计思路 将一个多位宽,且在不停变化的数据从一个时钟域传递到另一个时钟域是比较困难的. 同步FIFO的指针比较好确定,当FIFO counter达到上限值时 ...

  9. 黄聪:C#使用GeckoFx拦截监控Http数据

    找了整整两天,在大海捞针之后,终于在上古代码中找到了一个可用的.... 可以用喜极而泣来形容测试有效之后的心情!!! 跟cefsharp相比geckofx最大的优点就是模式更接近于IE,包括node. ...

  10. JavaScript 高级特性

    1. 原型Prototype 1.1 构造函数 所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量.对构造函数使用new运算符,就能生成实例,并且this变量会绑定 ...