返回介绍

11.3 反射:运行期类信息

发布于 2024-10-15 23:56:25 字数 2012 浏览 0 评论 0 收藏 0

如果不知道一个对象的准确类型,RTTI 会帮助我们调查。但却有一个限制:类型必须是在编译期间已知的,否则就不能用 RTTI 调查它,进而无法展开下一步的工作。换言之,编译器必须明确知道 RTTI 要处理的所有类。

从表面看,这似乎并不是一个很大的限制,但假若得到的是一个不在自己程序空间内的对象的句柄,这时又会怎样呢?事实上,对象的类即使在编译期间也不可由我们的程序使用。例如,假设我们从磁盘或者网络获得一系列字节,而且被告知那些字节代表一个类。由于编译器在编译代码时并不知道那个类的情况,所以怎样才能顺利地使用这个类呢?

在传统的程序设计环境中,出现这种情况的概率或许很小。但当我们转移到一个规模更大的编程世界中,却必须对这个问题加以高度重视。第一个要注意的是基于组件的程序设计。在这种环境下,我们用“快速应用开发”(RAD)模型来构建程序项目。RAD 一般是在应用程序构建工具中内建的。这是编制程序的一种可视途径(在屏幕上以窗体的形式出现)。可将代表不同组件的图标拖曳到窗体中。随后,通过设定这些组件的属性或者值,进行正确的配置。设计期间的配置要求任何组件都是可以“例示”的(即可以自由获得它们的实例)。这些组件也要揭示出自己的一部分内容,允许程序员读取和设置各种值。此外,用于控制 GUI 事件的组件必须揭示出与相应的方法有关的信息,以便 RAD 环境帮助程序员用自己的代码覆盖这些由事件驱动的方法。“反射”提供了一种特殊的机制,可以侦测可用的方法,并产生方法名。通过 Java Beans(第 13 章将详细介绍),Java 1.1 为这种基于组件的程序设计提供了一个基础结构。

在运行期查询类信息的另一个原动力是通过网络创建与执行位于远程系统上的对象。这就叫作“远程方法调用”(RMI),它允许 Java 程序(版本 1.1 以上)使用由多台机器发布或分布的对象。这种对象的分布可能是由多方面的原因引起的:可能要做一件计算密集型的工作,想对它进行分割,让处于空闲状态的其他机器分担部分工作,从而加快处理进度。某些情况下,可能需要将用于控制特定类型任务(比如多层客户/服务器架构中的“运作规则”)的代码放置在一台特殊的机器上,使这台机器成为对那些行动进行描述的一个通用储藏所。而且可以方便地修改这个场所,使其对系统内的所有方面产生影响(这是一种特别有用的设计思路,因为机器是独立存在的,所以能轻易修改软件!)。分布式计算也能更充分地发挥某些专用硬件的作用,它们特别擅长执行一些特定的任务——例如矩阵逆转——但对常规编程来说却显得太夸张或者太昂贵了。

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

大家要认识的很重要的一点是“反射”并没有什么神奇的地方。通过“反射”同一个未知类型的对象打交道时,JVM 只是简单地检查那个对象,并调查它从属于哪个特定的类(就象以前的 RTTI 那样)。但在这之后,在我们做其他任何事情之前,Class 对象必须载入。因此,用于那种特定类型的.class 文件必须能由 JVM 调用(要么在本地机器内,要么可以通过网络取得)。所以 RTTI 和“反射”之间唯一的区别就是对 RTTI 来说,编译器会在编译期打开和检查.class 文件。换句话说,我们可以用“普通”方式调用一个对象的所有方法;但对“反射”来说,.class 文件在编译期间是不可使用的,而是由运行期环境打开和检查。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文