技术开发 频道

看Reflection如何增加程序的弹性

  【IT168技术评论】在不更动已编译好程序代码的情况下,却能大幅地影响程序的行为,这便是Reflection的动态威力所在

  许多接触过像Java及C#这类程序语言的程序人,或许对「Reflection(反射)」 这个名词不陌生,但实际上将这个技巧运作在日常开发工作的程序设计者,可能就并不那么多了。

  「Reflection」这个名词,在维基百科的解释是「计算机程序用以观察自身,及修改自身结构和行为的过程」。事实上,透过Reflection技巧,程序在执行时期本身便能够得知自己的外观长相,并且自我修改,甚至自我复制。

  Reflection的作用:得知自己的外观,甚至自我修改与复制

  支持Reflection机制的程序语言众多,大多数都是脚本式(Scripting Language)或是以虚拟机器为基础的程序语言,例如Java、C#、Smalltalk、Python、Ruby、PHP、Perl等。甚至JavaScript也支持Reflection。

  Reflection机制究竟能为程序提供什么样的作用?为什么程序设计者需要动用到Reflection?针对诸如此类问题的答案,还是要回到为什么程序需要在执行时期得知自己的外观长相,甚至进一步自我修改、复制。

  相对于「执行时期」,未使用Reflection机制的程序代码,在编译时期便已为编译器所见。对这样的对象导向程序而言,当某个类别A存在与另一个类别B的互动时,类别B在编译时期的长相,势必已经已为类别A所了解。

  举例来说,对于C++程序而言,类别A欲与类别B互动(例如呼叫它的函数),编译器在编译类别A的程序代码时,必须也要能够得知类别B的宣告及定义。相较于这样的限制,Reflection则让你的程序不必在编译时期便确定此事,而是让程序得以在执行时期,根据一些外在的信息,决定操作的对象以及操作的方式,毋需于编译时期便确定、同时写死这些事情。

  由此可以推想,Reflection是一个十分动态的特性,而且看起来可以为程序注入许多的弹性。

       运用Reflection便能审视自身的特性

  在解释究竟Reflection能够带来什么好处之前,先来看看具体的Reflection机制,以明白透过常见的Reflection支持,在程序中究竟能做到那些事情。我以Java为例介绍,目的不在介绍Java完整的Reflection API,而是透过Java,帮助大家了解Reflection的一般性概念。

  在Java中Relfection机制的源头,就是一个叫「Class」的class(在C#中有一个相似的类别,则叫做Type)。这个类别有点特殊,原因在于此类别的每一个对象都用来表示系统中的每一个类别。

  具体来说,每个Class对象都描述了每个类别的相关信息,也提供你透过它可以进行的一些操作。想要开始Reflection的动作,就必须先取得Class类别的对象。最常被运用到的两个途径,一个便是Object(所有对象皆继承的类别)所提供的getClass()函数,另一个则是Class类别所提供的forName()静态函数。

  前者让你得以取得一个对象(尤其是类型未知的对象)所属的类别,而后者则让你得以指定一个类别的名称后,直接得到该类别对应的Class对象。

  有了Class对象之后,便能「审视」自身的特性,这些特性包括了它隶属于那个Package、类别本身究竟是Public还是Private、继承自那一类别、实作了那些接口等。更重要的是,你可以得知它究竟有那些成员变量以及成员函数(包括建构式)
 

0
相关文章