`
wanghailiang333
  • 浏览: 202077 次
  • 性别: Icon_minigender_1
  • 来自: 广西
社区版块
存档分类
最新评论

[转]java范型研究

 
阅读更多

原文地址:http://blog.csdn.net/m13666368773/article/details/7951223

 

Java的泛型在代码中引用时,形式上很类似于普通的类,可以用来声明对象、方法的参数与返回值类型,甚至还可以作强制类型转换。因此,容易误认为泛型是一个“类名的变量”,当泛型类被参数化引用的时候,这个“变量”就被“赋值”为实际类。事实上这种认识是一个误区。

 

理论上说,Java中的类是由对应的.class文件的字节码来定义的,类在其编译时就会产生.class文件,与其如何被引用没有任何关系,当然更不可能与引用时的参数相关。编写泛型类时,也无从获取实际引用时的参数类,如Class clz=T.class这样的语句是无法通过编译的(考虑到引用时参数类可以是通配符,这点也就不奇怪了)。

 

既然泛型不是类,也不能获取引用时的参数类,那么以泛型声明的对象,是以什么类型编译的呢?答案是声明泛型时的上界类。为了证实这一点,来看一个最简单的自定义泛型类,只包含一个泛型声明的属性t及其get和set方法:

 

用jdk提供的javap工具可以查看.class文件的汇编代码,结果如下:

 

可以看到,类体中用到的泛型T,编译后都替换成了其上界类Number,而泛型特征在编译后被完全抹去了。如果反编译GenericClassTest.class文件,可以看的更清楚:

 

 

鉴于这种特性,在编写泛型类代码的时候要尤其谨慎使用泛型进行强制类型转换,如T t=(T)(对象);这样的语句在编译时会被认作是强制类型转换到泛型T的上界。由于编译器无从得知T的准确类型,这种转换无法用instanceof关键字预先进行匹配性的判断(instanceof T无法通过编译)。因此,如果使用不当,就会带来强制类型转换异常的隐患,尤其是转换后的结果被引用的时候。如下是一个刻意造成这种错误的例子:

 

以上的泛型类在get方法中给泛型属性t强制赋值一个字符串。由于T的编译上界类是Object,这个语句可以通过编译(但是会触发“未经检验的类型转换”警告)。引用时,声明了一个以Integer为参数的对象gct,在gct的作用域(main函数)中,其属性t被编译器认为是Integer类型,因此将其赋值给整数对象i,编译也不会有问题。但是运行时就会出现类型转换异常

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

    at test.GenericClassTest.main(GenericClassTest.java:13)

 

既然泛型类编译后只与泛型上界有关,为何在使用泛型类的对象时,又表现出强类型的特征呢(例如无法向一个ArrayList<String>声明的对象中add一个整数)?事实上这是Java编译器在引用泛型类的时候做了一次转义。为此写一个测试方法:

 

方法中声明了一个泛型GenericClassTest的对象,引用参数为Integer,并且执行了一次set和get方法。反编译.class文件,相应方法代码如下:

 

可以看到,代码中同样没有泛型特征,说明编译器在正式编译前,做了一步“预处理”,将涉及泛型引用的对象强制转换为泛型参数所指定的类型,也就是Integer类(注:如果声明泛型对象是参数带有通配符,则原先的get和set方法只有一个可以被引用:指定上界时只能使用get方法,指定下界时只能使用set方法,否则编译不通过。原因涉及通配符捕获概念,参见http://www.ibm.com/developerworks/cn/java/j-jtp04298.html

 

接下编译器才进行“真正的编译”,生成.class文件。

 

这种预处理有什么用呢?好处就是编译器写好了一套规范来实现强制类型转换,使得从使用外层看带参的泛型可以当作强类型来用。如果有不正确的类型操作,在编译阶段就会及时报错。

分享到:
评论

相关推荐

    Thinking in java4(中文高清版)-java的'圣经'

    1.8 单根继承结构 1.9 容器 1.9.1 参数化类型(范型) 1.10 对象的创建和生命期 1.11 异常处理:处理错误 1.12 并发编程 1.13 Java与Internet 1.13.1 Web是什么 1.13.2 客户端编程 1.13.3 服务器端编程 1.22 总结 第...

    论文研究-基于Java的迁移工作流管理系统原型的实现研究.pdf

    迁移工作流范型是近年来工作流研究的新方向。根据迁移工作流管理系统框架,以移动Agent技术为基础,采用Java为开发语言,开发了迁移工作流管理系统原型Migflow。描述了Migflow的内部结构,给出了实现方案,并对迁移...

    java面向对象代码实例

    面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计范型,它将现实世界中的事物抽象为程序中的对象,通过对象之间的交互来实现程序的功能。在Java中,面向对象主要体现在类、对象、封装、继承和...

    多编程语言环境下的结构体应用指南:C/C++、Python与Java中的结构体概念和实现

    通过对多个实例的研究,可以帮助理解不同编程范型之间的差异性和共通之处,促进对结构化编程思维的理解。 其他说明:本文不仅涵盖了结构体的基本语法规则和操作手法,而且讨论了一些高级主题,比如在C++中结构体和类...

    软件重构方法的研究(吉林大学博士学位论文)

    吉林大学博士学位论文 关键词:软件重构方法;软件维护;程序转换;行为保留;程序结构改善;...Java语言接口;面向方面范型;横切关注点;方面挖掘; 静态模型;动态模型;逆向软件工程;对象状态模型.

    论文研究-网格GIS及其实现技术.pdf

    综上所述,网格GIS的研究涉及了GIS体系结构设计、Java网络通信、XML文档处理、空间数据库设计等多个IT领域知识。它的实现需要综合利用各种技术,包括但不限于Java编程、XML技术、数据库技术、网络通信协议等,从而...

    华南理工大学分布式计算试卷

    第一章涵盖了分布式计算、集中式计算、JAVA程序、JAVA线程等基本概念,以及分布式计算与集中式计算的区别和优缺点。同时,本章还介绍了CAP理论及其在NoSQL数据库中的应用,以及进程间通信(IPC)的相关概念、事件...

    JXTA技术手册/奥克斯(Oaks,s.),切 中文 高清版

    在2001年2月,Sun公司宣布了Java网络技术中的一种创新性的范型:JXTA。倡导者是BillJoy,他是Sun公司的主要技术革新者。JXTA提供了一种革命性的框架,允许Java程序员利用新的点对点(P2P)网络协议,勿须考虑底层的...

    分布式对象模型应用技术研究.pdf

    本文主要探讨了分布式计算的十大范型中的分布式对象模型,以及在此模型下的一些关键技术,如远程方法调用(RMI)、对象请求代理(ORB)和构件技术。 远程方法调用(RMI)是Java平台上的一个重要特性,它使得一个...

    编程思想下篇

    1.9.1 参数化类型(范型) 1.10 对象的创建和生命期 1.11 异常处理:处理错误 1.12 并发编程 1.13 Java与Internet 1.13.1 Web是什么 1.13.2 客户端编程 1.13.3 服务器端编程 1.22 总结 第2章 一切都是对象 2.1 用...

    编译原理课件导论--总体编译过程介绍

    【编译原理】是计算机科学中的一个重要分支,主要研究如何将高级编程语言转换为机器能够理解和执行的低级语言,如汇编或机器语言。编译程序,也称为编译器,是这一过程的核心工具。 1. **编译程序的概念**: 编译...

    《JavaScript语言精髓与编程实践》精选版--动态函数式语言精粹

    尤其在使用JavaScript的开发者群体里,深入了解该语言的本来就不多,研究语言特性的就更少了。 《JavaScript语言精髓与编程实践》精选版从JavaScript 无关的角度综论这些语言的产生发展,以及特性的概要。作为纯...

    分布式原理与源码

    在《分布式系统原理与范型》这本书中,作者可能详细介绍了分布式系统的特征,如透明性、一致性、容错性、可扩展性和性能优化等。这些特性对于理解分布式系统的设计目标至关重要。 分布式系统的核心概念包括数据复制...

    《JavaScript语言精髓与编程实践》精选版

    尤其在使用JavaScript的开发者群体里,深入了解该语言的本来就不多,研究语言特性的就更少了。 本迷你书摘引了《JavaScript语言精髓与编程实践》一书有关语言讨论的关键章节(主要在第三、四、五章),从JavaScript...

    基于项目的软件工程:面向对象方法

    本书不依赖于具体的程序设计语言(必要的代码示例用Java给出),并采用统一建模语言(UML)的子集来为软件建模,解释学生工作中需要用到的符号。 本书为学生而写,可作为计算机专业本科生、非计算机专业研究生的软件...

    Curl IDE6.0

    CurlCurl是由美国国防部高级研究项目代理资助,马萨诸塞州科技学院的David A. Kranz开发的Web开发语言, HTML语言的创建者Tim Berners-Lee也参与其中,并扮演了重要的角色。  Curl语言是一种编程语言,它被设计...

    PETSHOP4.0全面分析

    Microsoft .NET Pet Shop 4是一款由微软推出的基于ASP.NET 2.0的示例应用,它以其全新用户界面和优化的架构,成为研究.NET平台开发的重要参考。Pet Shop系列自推出以来,就成为了.NET和Java性能比较的焦点,因为它...

    WEKA进行数据挖掘

    这是80/20范型的一个很好的例子——甚至更进一步可以是90/10范型。您用所谓的数据挖掘专家的10%的专业知识就能创建具有90%效力的数据挖掘模型。而为了补上模型剩下的10%的效力并创建一个完美的模型将需要90%额外的...

    计算机网络自顶向下

    书中强调了应用层的范型和编程接口,帮助读者在实际中能够快速学习和实现各种应用程序中的协议。随后,通过自顶向下的方法分析网络体系结构,让读者能够专注于网络所提供的服务内容,而不是仅仅停留在网络协议的抽象...

Global site tag (gtag.js) - Google Analytics