我的对于对象的内存分析应该还是没错的:
因为多态(动态绑定)虽然能在运行时期识别该具体调用哪个类的方法,但是对于非static的成员变量就不能很好的识别了(如果子类覆写了父类的非static成员变量,RTTI还是不能解决去哪里拿这个变量的问题)。所以还是我说的那句话,强制转换类型是会进行内存截取的,动态绑定只是截取后的表现特点。
然后我想了一下,还是可以有一个RTTI(运行时类型识别 RunTime Type Inentify)机制的,这样子在对象的内存里就不需要放一个方法的符号引用了,对象的内存里将只需要放非static的成员变量就行了。
如果像我上面那张图画的,每个对象的内存里都有指向自己方法的函数指针(符号引用),那么在创建这个对象的时候,对于父类的show()方法和子类的show()方法,他们分别要和方法区里的哪个类的show()方法的代码绑定,还有要有一个TI(Type Identify)机制来判断的,这个TI机制和上面的RTTI机制其实是一样的,伪代码如下:
if(该方法是static的){
从方法区的当前类的代码区去找show()方法;
}else{
从方法区的实际类的代码区去找show()方法;
}Father f=new Child();
f的当前类是Father,实际类是Child
那么我们就可以把这个TI机制给提取出来,让他变成在运行时期调用每个方法之前都会判断一次的RTTI机制,这样就把对象里方法的符号引用的空间给省下来了。所以这个show()方法一直是一个符号引用,对他只在编译期作基本的验证(判断这个符号引用“show”(包含方法名称以及该方法的参数类型、报错类型) 在不在调用它的对象的当前类的方法表里面,这样就实现了把子类转为父类时对子类方法的切割),然后在运行时期执行到这一行时才使用RTTI机制把符号引用解析为实际的直接引用(物理地址)。
上面这些都是我自己瞎编的,极有可能是错误的,但是互联网上的博客千篇一律,当我想知道对象里有没有成员方法而去搜索“对象的内存分析”的时候,网上的图只知道从栈里画一根线连到堆内的对象,这个对象连个父类都没有;当我想知道“向上强制类型转换的意义”的时候,网上的答案只会从工程学的角度告诉我说如果不写一个父类以后要更改大量的代码是很麻烦的。。。根本不谈细节到底有没有对内存的截取,这完全就是把上课老师说过的话粘贴到了博客上而已。
所以我就只能自己瞎猜了。(*>﹏<*)′
(>﹏<)′