`
gao_20022002
  • 浏览: 160228 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

think in java回顾整理之RTTI

    博客分类:
  • Java
阅读更多

运行期类型鉴定(RTTI)的概念初看非常简单——手上只有基础类型的一个句柄时,利用它判断一个对象的正确类型。

如何利用Java在运行期间查找对象和类信息:
一种是“传统”RTTI,它假定我们已在编译和运行期拥有所有类型;另一种是“反射”机制,利用它可在运行期独立查找类信息。

多形性是面向对象程序设计的一个常规目标。

类型信息在运行期是如何表示的?
这时要用到一个名为“Class对象”的特殊形式的对象,其中包含了与类有关的信息(有时也把它叫作“元类”)。
事实上,我们要用Class对象创建属于某个类的全部“常规”或“普通”对象。
对于作为程序一部分的每个类,它们都有一个Class对象。换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当地说,是保存在一个完全同名的.class文件中)。在运行期,一旦我们想生成那个类的一个对象,用于执行程序的Java虚拟机(JVM)首先就会检查那个类型的Class对象是否已经载入。若尚未载入,JVM就会查找同名的.class文件,并将其载入。所以Java程序启动时并不是完全载入的,这一点与许多传统语言都不同。
一旦那个类型的Class对象进入内存,就用它创建那一类型的所有对象。

Class对象和其他任何对象都是类似的,所以能够获取和控制它的一个句柄(装载模块就是干这件事的)。
为获得Class的一个句柄,一个办法是使用forName()。它的作用是取得包含了目标类文本名字的一个String(注意拼写和大小写)。最后返回的是一个Class句柄。

每个Class只有在它需要的时候才会载入。

“类标记”:
类标记不仅可以应用于普通类,也可以应用于接口、数组以及基本数据类型。
除此以外,针对每种基本数据类型的封装器类,它还存在一个名为TYPE的标准字段。TYPE字段的作用是为相关的基本数据类型产生Class对象的一个句柄。


RTTI形式包括:
(1) 经典造型,它用RTTI确保造型的正确性,并在遇到一个失败的造型后产生一个ClassCastException违例。
(2) 代表对象类型的Class对象。可查询Class对象,获取有用的运行期资料。
(3)关键字instanceof告诉我们对象是不是一个特定类型的实例(Instance即“实例”)

编译器能够自动上溯造型,编译器不允许自动下溯造型,除非明确指定一次这样的造型。

Class的newInstance()方法似乎是克隆(clone())一个对象的另一种手段。但两者是有区别的。利用newInstance(),我们可在没有现成对象供“克隆”的情况下新建一个对象。
利用newInstance()方法可以实现“虚拟构建器”。

用newInstance()创建的类必须有一个默认构建器。
没有办法用newInstance()创建拥有非默认构建器的对象,所以在Java 1.0中可能存在一些限制。
然而,Java 1.1的“反射”API(下一节讨论)却允许我们动态地使用类里的任何构建器。


编译器必须明确知道RTTI要处理的所有类。
(1) 基于组件的程序设计。“反射”提供了一种特殊的机制,可以侦测可用的方法,并产生方法名。通过Java Beans,可以为这种基于组件的程序设计提供了一个基础结构。
(2) 通过网络创建与执行位于远程系统上的对象。这就叫作“远程方法调用”(RMI),它允许Java程序使用由多台机器发布或分布的对象。

在Java 1.1中,Class类得到了扩展,可以支持“反射”的概念。
针对Field,Method以及Constructor类,它们都新增了一个库:java.lang.reflect。
这些类型的对象都是JVM在运行期创建的,用于代表未知类里对应的成员。
这样便可用构建器创建新对象,用get()和set()方法读取和修改与Field对象关联的字段,以及用invoke()方法调用与Method对象关联的方法。
此外,我们可调用方法getFields(),getMethods(),getConstructors(),分别返回用于表示字段、方法以及构建器的对象数组。
因此,匿名对象的类信息可在运行期被完整的揭露出来,而在编译期间不需要知道任何东西。

“反射”并没有什么神奇的地方。
通过“反射”同一个未知类型的对象打交道时,JVM只是简单地检查那个对象,并调查它从属于哪个特定的类(就象以前的RTTI那样)。
但在这之后,在我们做其他任何事情之前,Class对象必须载入。


RTTI和“反射”之间唯一的区别:
对RTTI来说:编译器会在编译期打开和检查.class文件。换句话说,我们可以用“普通”方式调用一个对象的所有方法;
对“反射”来说:.class文件在编译期间是不可使用的,而是由运行期环境打开和检查。

Class.forName()产生的结果不能在编译期间获知,所以所有方法签名信息都会在运行期间提取。可对一个编译期完全未知的对象进行实际的设置以及发出方法调用。

Java的要求是让我们尽可能地采用多形性,只有在极特别的情况下才使用RTTI。

RTTI的优点:
若基础类来自一个库,或者由别的什么东西控制着,RTTI便是一种很好的解决方案:可继承一个新类型,然后添加自己的额外方法。在代码的其他地方,可以侦测自己的特定类型,并调用那个特殊的方法。这样做不会破坏多形性以及程序的扩展能力,因为新类型的添加不要求查找程序中的switch语句。但在需要新特性的主体中添加新代码时,就必须用RTTI侦测自己特定的类型。
从某个特定类的利益的角度出发,在基础类里加入一个特性后,可能意味着从那个基础类衍生的其他所有类都必须获得一些无意义的“鸡肋”。这使得接口变得含义模糊。RTTI提供了一个更合理的解决方案,可将方法置入特定的类中——这样做是可行的。
RTTI有时能解决效率问题。

 

Class.forName用的是java的动态加载机制(RTTI),和反射我觉得是两码事。

分享到:
评论

相关推荐

    Think in Java(中文版)chm格式

    14.2.3 回顾Java Beans 14.3 堵塞 14.3.1 为何会堵塞 14.3.2 死锁 14.4 优先级 14.4.1 线程组 14.5 回顾runnable 14.5.1 过多的线程 14.6 总结 14.7 练习 第15章 网络编程 15.1 机器的标识 15.1.1 ...

    Java进阶教程之运行时类型识别RTTI机制

    主要介绍了Java进阶教程之运行时类型识别RTTI机制,在Java运行时,RTTI维护类的相关信息,比如多态(polymorphism)就是基于RTTI实现的,需要的朋友可以参考下

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm ------------------------------------------------- 本教程由yyc,spirit整理 ------------------------------------------------- “Thinking in Java...

    Thinking in Java简体中文(全)

    14.2.3 回顾Java Beans 14.3 堵塞 14.3.1 为何会堵塞 14.3.2 死锁 14.4 优先级 14.4.1 线程组 14.5 回顾runnable 14.5.1 过多的线程 14.6 总结 14.7 练习 第15章 网络编程 15.1 机器的标识 15.1.1 服务器和客户机 ...

    Thinking in Java 中文第四版+习题答案

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的...

    举例讲解Java的RTTI运行时类型识别机制

    主要介绍了Java的RTTI运行时类型识别机制,包括泛化的Class引用以及类型检查instanceof等知识点,需要的朋友可以参考下

    Thinking in Java(中文版 由yyc,spirit整理).chm

    “Thinking in Java”详细目录   写在前面的话 引言 1. 前提 2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 ...

    Java的RTTI和反射机制代码分析

    主要涉及了Java的RTTI和反射机制代码分析的相关内容,在介绍运行时类型识别的同时,又向大家展示了其实例以及什么时候会用到反射机制,内容丰富,需要的朋友可以参考下。

    Delphi的RTTI机制文档

    Delphi的RTTI机制文档

    JAVA_Thinking in Java

    14.2.3 回顾Java Beans 14.3 堵塞 14.3.1 为何会堵塞 14.3.2 死锁 14.4 优先级 14.4.1 线程组 14.5 回顾runnable 14.5.1 过多的线程 14.6 总结 14.7 练习 第15章 网络编程 15.1 机器的标识 15.1.1 服务器和客户机 ...

    MFC源代码 RTTI.02

    MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 RTTI.02MFC源代码 ...

    c++ RTTI解析

    c++ RTTI深度解析, 运行时类型识别技术

    个人收集的RTTI机制

    个人收集的RTTI机制....好的话就顶

    RTTI.zip_DELPHI RTTI_delphi_rtti

    delphi RTTI功能示例 演示如何在delphi 中使用rtti

    MFC的RTTI和动态创建仿真

    MFC框架仿真,实现RTTI和动态创建

    RTTI使用探讨与编码实现

    在C++中如果使用多态继承类,对于多态性的对象,在程序编译时可能会出现无法确定对象的类型的情况,这事就需要通过RTTI动态识别对象的类型。因此,本文探讨了RTTI的使用细节。同时,由于有些平台C++编译器(如...

    一种线程消息驱动及RTTI分发操作的示例

    blog文章:一种线程消息驱动及RTTI分发操作的示例

    RTTI.rar_rtti

    候老师讲的RTTI 资源难得 希望大家喜欢

    MFC RTTI代码(博客中使用资源)

    博客中使用的完整源码【MFC(2)】,仿真了 MFC 的 RTTI。博客地址: http://blog.csdn.net/raito__/article/details/51684826

    rtti.zip_rtti_zip

    Delphi RTTI usage example

Global site tag (gtag.js) - Google Analytics