虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员
--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。

http://m.blog.csdn.net/blog/seekcreation/40116455

虚函数表

成员方法的解析

java中方法分派指令:

invokespecial

invokevirtual

invokedynamic

involveinterface

静态类型,静态分派

实际类型,动态分派

成员数据解析

根据 java7虚拟机规范 , 成员数据解析过程描述如下:

为了将一个还没有解析的符号引用D解析成一个类(或者接口)C的一个成员,符号引用C必须被先解析。因此任何因在C被解析成类(或者接口)时失败导致抛出的异常都可以被解析符号引用D时抛出。如果C可以被解析成一个类(或者接口),则因D被解析成一个成员引用失败抛出的异常才可以被抛出。

  1. 如果C声明了和D符号引用(名称和描述符)一样的成员引用,则解析成功;
  2. 否则,解析过程递归到类C的直接实现(或者接口C直接继承)的接口中;
  3. 否则,如果C有父类S,则解析过程递归到S中;
  4. 否则,解析失败。

纵使上面解析成功,接着还会验证访问权限:

  1. 如果上面的解析过程解析失败,则直接抛出 NoSuchFieldError;
  2. 否则,如果没有对D没有 获取权限 ,则直接抛出 IllegalAccessError;
  3. 。。。

从上面的解析过程可以看到,对于成员数据的访问,虽然成员数据也和方法声明一样有访问限制,但Java并没有用不同的虚拟机指令来区分对不同访问限制的成员数据的访问,而是符号解析后统一进行访问权限的验证检查,而且还可以看出java语言中子类型中声明的成员数据可以覆盖父类型中声明的成员数据的语法在符号解析的规则中就可以实现。下面举例说明四条成员数据访问相关的指令。

package com.baidu.test;

public class T {
private int data = 100;
public static void main(String[] args) {
T t = new T();
System.out.println(t.data);
}
}

部分常量池数据:

构造函数中对data赋值:( putfield)

main函数中读取data值:(getfield)

package com.baidu.test;

public class T {
static class A {
static int data = 1000;
} static class B extends A { } public static void main(String[] args) {
System.out.println(B.data);
}
}

部分常量池数据:

类A的静态构造初始化块中给data赋值(putstatic)

main方法中读取data的值(getstatic)

稍微留意下可以发现,虽然data是声明在父类A中,但是在T中使用A的子类B访问data时,常量池中依然是描述为对B的成员data访问(见 T的常量池 #22)

最新文章

  1. 文件IO操作..修改文件的只读属性
  2. zabbix3.0 微信告警
  3. SQL Server去掉字段内的双引号
  4. 【Jetlang】一个高性能的Java线程库
  5. JS 代码编一个倒时器
  6. acm-字符串整理
  7. USACO 2.4 Cow Tours
  8. 震荡信号Simulink仿真
  9. ExoPlayer Talk 01 缓存策略分析与优化
  10. java输出日志
  11. OpenStack Paste.ini详解(一)
  12. 基于Redis实现分布式锁
  13. JavaCC的TokenManager和Parser
  14. go语言之行--golang操作redis、mysql大全
  15. 解决spring 用@Value注入配置时候出现中文乱码问题
  16. 类的综合运用-complex的实现
  17. 对JVM的简单了解
  18. 批处理 ------ @、ECHO OFF、ECHO ON 的使用
  19. (转)Redis集群搭建与简单使用(最少需要 6个节点)
  20. Spark项目之电商用户行为分析大数据平台之(一)项目介绍

热门文章

  1. [bzoj1011](HNOI2008)遥远的行星(近似运算)
  2. Codeforces Round #343 (Div. 2) C. Famil Door and Brackets dp
  3. mysql错误10060
  4. .Net的差评
  5. [Eclipse插件] Eclipse设置Tab键为空格(ctrl+shirt+f格式化生效)!
  6. [转]SSIS高级转换任务—在Package中是用临时表是需要设置RetainSameConnection属性
  7. iOS:极光推送控制器跳转
  8. SVN配置常见错误
  9. 阿里云64位centos6.3系统上编译安装redis
  10. c#跟objective-c语言特性的对比