关于反射的用途是『降低模块间的耦合度』这个倒未必尽然

单就delphi来说,从实现上看,它的所谓反射是基于RTTI,而RTTI的出现按照官方的说法是为了实现RAD中窗体文件DFM的持久化而产生的,其实也不是针对DFM文件或TForm啦,由于TPersistent在声明的时候加上了{$M+},所以从TPersistent派生的对象都在编译的时候添加了RTTI,而在TComponent中又增加了对TReader和TWriter支持,说的准确一点、时髦一点RTTI是为了实现对象的持久化和反持久化,在Delphi3之后加入了接口,从而将COM引入,而在delphi6以后又加入了对接口的RTTI的支持,从而将SOAP也引入到了delphi之中,从这两个重大特性的加入上看到,除了Delphi对接口支持的越来越丰富,还有一点很重要的是Delphi很早就支持了远程方法调用RPC,对于RPC的支持并不是简单的对传输协议的支持,而是要在对象定义、编译层面对其实现的支持。尽管COM的RPC与SOAP的RPC在表象上是有所不同的,但我们其实可以断定,在Delphi6之后已经就可以对对象的方法动态调用了。事实上也确实如此,一切奥秘尽包含在TypInfo,IntfInfo,ObjAuto,Invoker这些单元之中,只可惜在Help中并没有体现。我记得李维发过这样一句叹息,说其实在Borland实验室中十年前就有很多天才很多很Cool的想法但是得不到老板的支持,最后只得痛惜离开Borland。我在翻看VCL代码的时候,相信这确实是真的,现在很多在.NET或Java上很时髦的特性,有多少是Delphi在语言层面上是不支持的呢,我们忽略了Delphi是因为它们还没有来得及被Borland的工程师推向前台、还没来得及将其做成框架发布出来,而这些工程师就被赶跑了。

  可能是误会了反射的意思,这里并不是指对另外单元中声明的引用,而是指在运行时可以获得代码的特性以及在运行时可以改变它的行为。这样说可能抽象一点,说的稍微形象一点,一般编译型语言中,程序中所有定义的变量和函数,它们是否被使用、如何被使用,都是要在编码的时候设定好全部的执行逻辑的,而运行时只是遵循其中一条或几条执行路径执行的,而所谓的反射就是要能够在运行时通过一个外部的控制来决定程序内部的执行行为,也就是说从逻辑上看,程序不再是一个闭包的逻辑系统,而可以依赖于外部的注入。简单的说程序的运行时结构是由许多代码段、堆和栈这三种内存块组成,而所谓的执行就是指内部逻辑可以访问到代码段中的所有定义,将函数代码放在栈上展开执行,在堆中间分配所需空间以及一些其他的诸如IO访问等行为的集合。所以,如果要实现外部的控制注入,即反射,至少需要满足能够访问类似代码段上数据而获得变量和函数定义的部分,其次还要能够控制函数在栈上展开执行。

Delphi这种基于RTTI信息而实现的反射和Java、.Net有显著的不同。由于Java、.Net是先将程序编译成bytecode或CIL,在将中间代码让VM来执行,所以在这一类语言上实现反射的基本方式是获得bytecode和CIL,这部分内容就类似于代码段上的信息,然后外部注入的逻辑被重新编译生成新的中间代码后再让VM执行,从而产生新的行为。在这种机制下,非但可以实现反射,而且还可以对中间代码实行反编译而获得原始代码。而Delphi对反射的实现和Java以及.Net有本质的不同,它将对象的字段和函数的信息编译进RTTI,在编码的时候将对象注册进一个全局的列表中,运行时通过访问该列表而获得所需的对象,再从对象的RTTI中获得字段和函数的信息,同时提供出一种可以在运行时执行对象方法的函数,也不需要再编译,于是就间接的实现了反射机制。但是我们也应该注意到Delphi的反射和Java相比,首先是并不能反射到所有的变量和函数,例如全局的函数,静态变量就不会获得,其次由于不存在中间代码,也不存在反编译的问题,当然,这些都不是重点。其实这些东西在Delphi6\7的时候就已经有了,因为要支持SOAP,在SOAP标准中有一个SOAP的RPC表示,也就是说SOAP在调用远程对象方法的时候,也就是通过字符串来驱动的,所以不但有对象的RTTI,也可以在声明接口的 时候添加{$M+}来编译进接口的RTTI,从而对接口方法也可以使用字符串来驱动。又因为最初的设计是针对SOAP的,所以在ObjAuto单元中ObjectInvoke方法不支持对象类型和指针类型,毕竟SOAP在远程调用方法时传物理地址是没有意义的,当然,Variant也是不支持对象类型的。

delphi 反射(原理)的更多相关文章

  1. Delphi反射

    最近在写一个框架,需要用到反射,与C# java这些原生支持反射的语言不同,delphi对反射的支持相对要弱一些,但也够用了,其实C#的大部分的思想还是从 delphi而来,毕竟都是安德鲁斯的杰作. ...

  2. Lua刚開始学习的人(一)--Lua 简单教学

    近期因为工作原因.临时木有<Oracle起步学习>续集.领导知道学习下Lua脚本语言.看了一周了.趁热打铁,留下点实用的东西吧. 本系列会主要针对宿主语言为 Delphi,原理都是一样的, ...

  3. Django 的 cbv

    Django 的 cbv 正如我们了解到的,Django 写视图函数有两种写法:cbv 和 fbv.cbv 提倡使用类来写,fbv 使用函数来 写.当然为了代码的重复行,官方更推荐使用 cbv. 写 ...

  4. Shaderlab-10chapter-立方体纹理、玻璃效果

    10.1.1天空盒子 window - Lighting - skyMaterial 创建mat,shader选自带的6 side shader 确保相机选skybox 如果某个相机需要覆盖,添加sk ...

  5. IoC原理-使用反射/Emit来实现一个最简单的IoC容器

    从Unity到Spring.Net,到Ninject,几年来陆陆续续用过几个IoC框架.虽然会用,但也没有一直仔细的研究过IoC实现的过程.最近花了点时间,下了Ninject的源码,研究了一番,颇有收 ...

  6. Java反射机制及IoC原理

    一. 反射机制概念 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义.在java中,只要给定类的名字, 那么就可以通 ...

  7. Android反射机制实现与原理

    本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或 ...

  8. JAVA的反射机制原理

    http://www.cnblogs.com/hongxinlaoking/p/4684652.html 一  反射机制的概念: 指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于 ...

  9. 【JAVA - 基础】之反射的原理与应用

    一.反射简介 反射机制指的是程序在运行时能够获取自身的信息.在JAVA中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息. 1.反射的应用 JDBC编程中的:Class.forName(& ...

随机推荐

  1. MyEclipse导入ant项目——Java编程思想

    北门煎饼东门串儿: <JAVA编程思想(Think in Java)>一书中提供了大量源代码,可是项目是用ant构建的.对于用惯了eclipse,netbeans等IDE的同学们可能有些手 ...

  2. Linux 进行反编译 或者 汇编

    Linux 进行反编译 或者 汇编 一.需要的工具 1.objdump 2. 3.

  3. 你早该这么玩Excel 读书笔记

    1. Excel用来分析数据,至少要有一份原始数据和对于的分类汇总数据,这两种数据在一项任务中,应该是存放在同一个Excel文档中的,在书籍中,把他们叫做源数据表和分类汇总表.用户输入源数据表,根据相 ...

  4. 在ThinkPHP3.x框架中实现将原创文章第一时间推送到百度收录

    前两天自己写的一篇文章“针对BootStrap中tabs控件的美化和完善”被别的网站给转载了,这也许是值得高兴的一件事情,但是有些网站并没有注明来源和作者.而去百度搜索这篇文章,排名第一的居然是那些转 ...

  5. 彻底删除sql server的方法

    请先确定是否把sql相关的东西删了,建议进行如下操作. 1.先下个Windows Install Clean Up,清理sql相关东西,要全部清理. 2.到控制面板--添加删除程序中看是否还有未删的. ...

  6. linux 神器之wget

    1.什么是Wget? 首页,它是网络命令中最基本的.最好用的命令之一; 文字接口网页浏览器的好工具. 它(GNU Wget)是一个非交互从网上下载的自由工具(功能).它支持http.ftp.https ...

  7. Using jQuery to add a dynamic “Back To Top” floating button with smooth scroll

    Ever read a really long blog post or article and then had to scroll all the way up to the top of the ...

  8. ARM-Linux S5PV210 UART驱动(6)----platform device的添加

    开发板是飞凌OK210 arch/arm/mach-s5pv210/mach-smdkc110.c 首先是UART的寄存器默认配置信息: /* Following are default values ...

  9. C语言socket编程--每日签到

    前几天写了个python的每日签到,你运行还得借助crontab,很是不爽.....正好前几天看了个关于c编写daemon进程,加上自己那点可怜的socket知识,于是我们重操旧页,C语言版的每日签到 ...

  10. cmd&Linux 下使用mysql全记录

    php mysql数据库常用cmd命令集 show databases; 显示数据库 create database name; 创建数据库 use databasename; 选择数据库 drop ...