Java为什么能够支持Reflection?答案是Java运行时仍然拥有类型信息,它包含了这个类一切:它有哪些字段、哪些方法,各是何种保护级别等等,还有这个类依赖于哪些类。在Java中,类信息以对象的形式存放,这些对象是一种元对象,它们的类型就是Class。拥有了这些信息,无论是动态创建对象还是调用某些方法都是轻而易举的。在C++中,通过RTTI(运行时类型识别),我们也可以知道类的一些信息,但为什么C++中却没有Reflection,原因是类型信息不完整。RTTI这个名字本身就告诉我们,C++的类型信息是用来进行类型识别的,因此,它也不需要其它额外的信息。并不是C++无法做到这一点,而是C++不希望给用户增加额外的负担。有所得,必然有所失,因此,C++放弃了元对象。关于这一点,C++之父Bjarne Stroustrup在他的《C++语言的设计与演化》的14.2.8节中进行了深入的讨论。 元对象是Java Reflection的物质基础,那它的精神基础又是什么呢?Java为什么要支持Reflection?经过上面的讨论,我们把这个问题再进一步,为什么Java要提供元对象? 讨论这个问题,我们还要拉回到十年前,那时Java刚刚来到正式登上历史的舞台。Java实际上诞生在这之前的数年,那时候还叫Oak,环境所限使得这一划时代的杰作甫一出炉便被束之高阁。当Netscape掀起了为网络大戏的序幕,Java得以凤凰涅槃,这其中很重要的一个原因就是Java是以网络为中心的。 仔细观察,我们会发现,Java的整个基础架构的设计都是为网络服务。首当其冲的便是Java中最著名的跨平台。其实,在Java之前的年代,人们也需要考虑平台之间的可移植性,但这种移植大多数集中在源码一级,这也就是C语言可以流行的原因之一,在单机环境下,平台的差异并不那么明显。网络的出现使平台之间差异凸现出来,因为网络可能会连接各种各样的计算机和设备。没错,还有设备,你也许知道Java最初的开发是和嵌入式设备相关的。一旦应用可以跨平台,程序开发和后期管理维护工作将得到极大的简化,可移植性也从源码级晋升到二进制级(Java字节码)。所以,跨平台实际上也是为了网络打基础。Java中另一个重要的买点——安全性与网络之间的关系更为密切,谁都可以想出几条理由,把二者关联起来。 有了元对象,Reflection也成了一件顺其自然的事情。有了Reflection,Java也就拥有了动态扩展的能力,这样就可以极大的提高程序的灵活性。 关于Java基础结构对网络的支持还可以再说几句。class文件经过了精心的设计,本身相当紧凑,其目的就是为了方便在网络上传输,而JAR文件的出现,其目的也是为了方便网络传输,因为如果每次只传输一个类,大量的时间都被浪费在建立网络连接的过程中,JAR文件使得一次传输多个类成为可能,而且我们还知道JAR文件中的数据是经过压缩的,这样可以进一步减少下载时间。Java基础架构对网络的支持,《深入Java虚拟机》(第二版)的4.3节进行了很好阐述,有兴趣不妨看一下。 对Reflection思考让我有机会对Java本身的设计进行深入的思考。一个好的软件设计需要一个核心理念作为支撑,所有的一切都是围绕核心进行的,而对于Java,这个核心就是网络。 |
|
来自: bluecrystal > 《java》