在开始正文之前,我先来区分一下标题的这两个词的含义。所谓类型对象,就是指运行时为加载到应用程序中的类型在堆中分配的一块内存区域,该区域中,包括的信息有:类型对象指针、同步索引块、静态字段、指向基类的引用字段、方法列表等等。而类实例对象,就是指当使用关键字 new 初始化一个对象实例时,在堆中分配的一块内存区域,这里面包含的信息有:类型对象指针、同步索引块、实例字段,以及基类的实例字段,这里的类型对象指针,就是指向该类的类型对象的。我们还是先引入一张图。
上图中,左边部分为代码调用,右边部分为堆栈和堆上的内存分配情况。其中,Manager 是派生自 Person 类。
当调用 Person 的静态方法 Person.CompareAge 时,直接根据 Person 的类型去寻找类型对象,然后调用方法即可。
当执行 p.GetName 方法时,根据 p 所对应的类型去寻找类型对象,然后找到对应的方法,JIT 编译器生成相应的代码后执行即可,如没找到,可根据“指向基类的字段”去寻找基类中是否有匹配的方法,直到 System.Object 类。
当执行 p.ShowPersonInfo 方法时,因为该方法是虚方法,所以首先会根据变量p , 找到其实际引用的实例的对象类型,然后根据这个类型去寻找类型对象,找到相应的方法执行。