何为泛型擦除

何为泛型擦除何为泛型擦除要理解泛型的擦除 首先要知道泛型的产生 泛型是 JDK1 5 才添加到 Java 中的 也就是说 JDK1 5 之前是没有泛型这一说的 例如 Comparable 接口在 JDK1 5 之前是如下定义的 publicinterf publicintcom Objecto 在 JDK1 5 或之后就采用了泛型 具体如下 publi

何为泛型擦除

        要理解泛型的擦除,首先要知道泛型的产生。

        泛型是JDK1.5才添加到Java中的,也就是说JDK1.5之前是没有泛型这一说的。例如:Comparable接口在JDK1.5之前是如下定义的:

        public interface Comparable {

                public int compareTo(Object o)

        }

        在JDK1.5或之后就采用了泛型,具体如下:

        public interface Comparable

{

                public int compareTo(T o)

        }

        Java作为一门程序设计语言,需要保证没有使用泛型的代码能在JDK1.5及以后的VM上运行,也就是兼容性的问题。

        为了解决这种代码的的兼容性,Java提供了泛型擦除(Erasure)。下面先看一个例子:

程序清单1 TestGenericErased.java

import java.util.ArrayList; import java.util.List; / * @author Administrator * */ public class TestGenericErased { public static void main(String[] args) { List       list1 = new ArrayList         (); list1.add("solo"); List           list2 = new ArrayList             (); list2.add(999); System.out.println("-------------------"); System.out.println("输出字符串:" + list1); System.out.println("输出整数:" + list2); System.out.println("-------------------"); System.out.println(list1.getClass()); System.out.println(list2.getClass()); System.out.println("-------------------"); System.out.println("判断list1和list2两个列表的类是否相同:" + (list1.getClass() == list2.getClass())); } }                  

运行结果:

------------------- 输出字符串:[solo] 输出整数:[999] ------------------- class java.util.ArrayList class java.util.ArrayList ------------------- 判断list1和list2两个列表的类是否相同:true

        上面的代码有两个不同的ArrayList:ArrayList

和 ArrayList

,前一个是保存整数的列表,后一个事保存字符串的列表,是两个具有不同参数化类型的ArrayList。但是通过比较它们的 Class 对象,运行结果输出的是 true。这说明在代码运行过程中,JVM虚拟机将它们视为同一个类:class java.util.ArrayList。

        为什么会是这样的结果呢?编译器做了什么?

        为了解决前面所说的兼容性问题,编译器需要做一些擦除的工作,通俗地说:编译器擦除掉在代码中与泛型类型有关的信息,这样最后生成出来的代码(字节码文件)其实是没有了泛型的代码,也就是说泛型基本上由编译器来实现,由编译器执行类型检查和类型推断,然后在生成字节码之前将其清除掉,虚拟机并不知道也不关心是否存在泛型。这样的话,泛型和非泛型的代码就可以混合运行,保证了代码的兼容性。

        还需要说明的是:在使用泛型时,会有一个对应的类型叫做原生类型(raw type),泛型类型会被擦除到原生类型,例如:前面的代码中,ArrayList

()会被擦除到ArrayList,ArrayList

()被擦除到ArrayList,由于擦除,在虚拟机中无法获得任何类型信息,虚拟机只知道原生类型。

        为了更进一步了解擦除,下面使用DJ Java Decompiler反编译工具对TestGenericErased.java源文件编译后的TestGenericErased.class字节码文件进行反编译,其反编译的代码如下:

程序清单2 TestGenericErased.class反编译后的代码

// Decompiled by DJ v3.12.12.100 Copyright 2015 Atanas Neshkov  Date: 2017/11/18 星期六 17:39:45
// Home Page:  http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   TestGenericErased.java

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

public class TestGenericErased
{

    public TestGenericErased()
    {
    }

    public static void main(String args[])
    {
        ArrayList arraylist = new ArrayList();
        arraylist.add("solo");
        ArrayList arraylist1 = new ArrayList();
        arraylist1.add(Integer.valueOf(999));
        System.out.println("-------------------");
        System.out.println((new StringBuilder()).append("\u8F93\u51FA\u5B57\u7B26\u4E32\uFF1A").append(arraylist).toString());
        System.out.println((new StringBuilder()).append("\u8F93\u51FA\u6574\u6570\uFF1A").append(arraylist1).toString());
        System.out.println("-------------------");
        System.out.println(arraylist.getClass());
        System.out.println(arraylist1.getClass());
        System.out.println("-------------------");
        System.out.println((new StringBuilder()).append("\u5224\u65ADlist1\u548Clist2\u4E24\u4E2A\u5217\u8868\u7684\u7C7B\u662F\u5426\u76F8\u540C\uFF1A").append(arraylist.getClass() == arraylist1.getClass()).toString());
    }
}

 

        对比程序清单1和程序清单2,在程序清单2中没有了泛型,程序又回到Java泛型出现之前的写法,泛型类型都变回了原生类型ArrayList,具体是:

程序清单1

程序清单2

List

ArrayList

ArrayList

()

ArrayList

List

ArrayList

ArrayList

()

ArrayList

 

参考网址:

1.https://www.cnblogs.com/drizzlewithwind/p/6101081.html

2.http://justjavac.iteye.com/blog/

3.http://blog.csdn.net/lonelyroamer/article/details/

4.https://www.cnblogs.com/xltcjylove/p/3671943.html

5.https://www.cnblogs.com/LinkinPark/p/5232980.html

6.http://blog.sina.com.cn/s/blog_7ffb8dd501012ku9.html

7.http://blog.csdn.net/yuhongye111/article/details/










版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177023.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午8:30
下一篇 2026年3月26日 下午8:30


相关推荐

  • 几种java反编译软件的安装以及使用总结

    几种java反编译软件的安装以及使用总结公司要和别的公司合作,有些代码不希望让他们知道,最近老大们在弄代码混淆的事,而我就做起了测试代码混淆的工作。印象笔记更新之后不能用了,就整理在博客上吧。下面是在网上找的几种反编译软件的安装以及使用:一、JD-JUI官网下载链接:http://jd.benow.ca/下载之后解压,点击“jd-gui.exe”运行:直接将".jar"文件拖入进去即可查看里边的“.class”文件,如上图所示。二:Lu…

    2022年6月3日
    49
  • 【图像处理算法】Hough变换

    【图像处理算法】Hough变换参考 1 https www zybuluo com lutingting note 数字图像处理的 MATLAB 实现 第二版 RafaelC Gonzalez3 MATLAB 帮助文档 Hough 变换于 1962 年由 PaulHough 提出 是一种使用表决方式的参数估计技术 其原理是利用图像空间和 Hough 参数空间的线 点对偶性 把图像空间

    2026年3月26日
    2
  • 利用前序和中序遍历构建二叉树的递归算法_二叉树先序遍历和后序遍历正好相反

    利用前序和中序遍历构建二叉树的递归算法_二叉树先序遍历和后序遍历正好相反前言在前两篇文章二叉树和二叉搜索树中已经涉及到了二叉树的三种遍历。递归写法,只要理解思想,几行代码。可是非递归写法却很不容易。这里特地总结下,透彻解析它们的非递归写法。其中,中序遍历的非递归写法最简单,后序遍历最难。我们的讨论基础是这样的:

    2025年10月23日
    6
  • 经济基础知识(初级)【17】

    经济基础知识(初级)【17】1.党的十八大报告中概括的科学发展观最鲜明的精神实质包括()A.解放思想B.实事求是C.与时俱进D.求真务实E.城乡协调2.下来金融业务中,属于投资银行业务的有()A.为工商企业代理证券买卖B.向工商企业提供中长期贷款C.投资工商企业股票D.参与工商企业并购重组E.向消费者提供消费贷款3.下来会计要素中,反映企业财务状况的有()A.收入B.资产C.负债D.费用E.所有者权益4.下来数据整理与显示方法中,适用于顺序数据的有()A.圆形图B.直方图C.累积

    2022年5月28日
    43
  • java list和数组转换_java list转string

    java list和数组转换_java list转string使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。说明:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。…

    2022年8月23日
    14
  • css怎么实现背景图片自适应窗口大小_html5背景图片自适应

    css怎么实现背景图片自适应窗口大小_html5背景图片自适应本篇文章给大家介绍html背景图片自适应窗口大小的方式。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。background-size:cover会把图片拉伸至足够大,但是背景图片有些部分可能显示不全效果大窗口小窗口background-size:contain把图片拉伸至最大,完全显示图片大窗口小窗口推荐学习:html视频教程…

    2026年4月17日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号