delphi 反射(原理)

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

单就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也是不支持对象类型的。

时间: 2024-10-13 12:22:19

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

Lua初学者(一)--Lua 简单教学

</pre></p><p><span style="font-family: 'Courier New'; font-size: 18px;">最近由于工作原因,暂时木有<<a target=_blank href="http://blog.csdn.net/zhuzhuyule/article/details/40404473" style="color: rgb(0, 0, 0); text-

敏捷估算扑克

原文地址:http://www.uml.org.cn/SoftWareProcess/201108264.asp 敏捷扑克是什么? 其实应该叫“估算扑克”更准确一些,本质上是扑克牌,基于Delphi估算原理,可以快速估算出需要的数字. 关于扑克牌上的数字 估算扑克牌上的数字,有的牌是自然数排列,有些是斐波纳契数,有些则是不连续自然数.具体选用哪种扑克,要根据被估算的内容的跨度大小而定,如果估算值跨度在10倍以内,那么采用顺序自然数比较好,如果数值跨度较大,达到10倍以上,那么采用斐波纳契数比较好

李开复给中国学生的第四封信:大学四年应是这样度过(下)

培养兴趣:开拓视野,立定志向 孔子说:“知之者不如好之者,好之者不如乐之者.”我在“给中国学生的第三封信”中曾深入论述了快乐和兴趣是一个人成功的关键.如果你对某个领域充满激情,你就有可能在该领域中发挥自己所有的潜力,甚至为它而废寝忘食.这时候,你已经不是为了成功而学习,而是为了“享受”而学习了.在“第三封信”中,我也曾谈到我自己是如何在大学期间放弃了我不感兴趣的法律专业而进入我所热爱的计算机专业学习的. 有些同学问我,如何像我一样能找到自己的兴趣呢?我觉得,首先要客观地评估和寻找自己的兴趣所在:

Django 的 cbv

Django 的 cbv 正如我们了解到的,Django 写视图函数有两种写法:cbv 和 fbv.cbv 提倡使用类来写,fbv 使用函数来 写.当然为了代码的重复行,官方更推荐使用 cbv. 写 cbv 时,写好 class 类视图,然后在 url 中调用 class 的 as_view() 函数,以前一直以为只要会调 用即可,没有去理解内涵.当然 fbv 直接执行函数即可.今天来看一看 cbv 方式的源码. 在 PyCharm 中进入 as_view 的源码,发现其是一个 classmet

Android反射机制实现与原理

本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 在Java中的反射机制,被称为Reflection(大家看到这个单词,第一个想法应该就是去开发文档中

Java反射机制及IoC原理

一. 反射机制概念 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 类中有什么信息,利用反射机制就能可以获得什么信息,不过前提是得知道类的名字. 二. 反射机制的作用 在运行时判断任意

java的反射机制原理

一  反射机制的概念: 指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法.这种动态获取信息,以及动态调用对象方法的功能叫java语言的反射机制. 二  反射机制的应用: 生成动态代理,面向切片编程(在调用方法的前后各加栈帧). 三  反射机制的原理: 1  首先明确的概念: 一切皆对象----类也是对象. 2  然后知道类中的内容 :modifier  constructor  field  method. 3  其次明白加载: 当An

利用反射模拟一个spring的内部工作原理

这个简单的案例是实行了登录和注册的功能,没有链接数据库. 在bean中id 是唯一的,id和name的区别在于id不能用特殊字符而name可以用特殊字符,比如:/-\.... 1 package com.obtk.reflect; 2 3 public class Logon { 4 /** 5 * 帐号密码长度大于六位字符就成功,否则失败! 6 * */ 7 public String select(String name, String pass) { 8 if (name.length()

MyBATIS插件原理第一篇——技术基础(反射和JDK动态代理)(转)

在介绍MyBATIS插件原理前我们需要先学习一下一些基础的知识,否则我们是很难理解MyBATIS的运行原理和插件原理的. MyBATIS最主要的是反射和动态代理技术,让我们首先先熟悉它们. 1:Java反射技术 在Java中反射技术已经大行其道,通过不断的优化性能得到了巨大的提高,而反射技术使得Java的可配置性大大提高.让我们来写一个服务打印hello + 姓名. import java.lang.reflect.InvocationTargetException; import java.l