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

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)

java 重载和多态的区别的更多相关文章

  1. java重载和重写的区别

    一.重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现 ...

  2. java基础疑难点总结之成员变量的继承,方法重载与重写的区别,多态与动态绑定

    1.成员变量的继承 1.1要点 子类用extends关键字继承父类.子类中可以提供新的方法覆盖父类中的方法.子类中的方法不能直接访问父类中的私有域,子类可以用super关键字调用父类中的方法.在子类中 ...

  3. [Java]重载,重写以及继承,多态的区别

    转自:http://android.blog.51cto.com/268543/53181 什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承. ...

  4. 2017.10.10 java中的继承与多态(重载与重写的区别)

    1. 类的继承 继承是面向对象编程技术的主要特征之一,也是实现软件复用的重要手段,使用继承特性子类(subclass) 可以继承父类(superclass)中private方法和属性,继承的目的是使程 ...

  5. Java 学习(12):重写(Override)与重载(Overload) & 多态

    目录 --- 重写 --- 重载 --- 多态 重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重写的好处在于子类可 ...

  6. C++和java多态的区别

    C++和java多态的区别 分类: Java2015-06-04 21:38 2人阅读 评论(0) 收藏 举报  转载自:http://www.cnblogs.com/plmnko/archive ...

  7. C++中的重载隐藏覆盖&&JAVA中的重载覆盖&&多态

    class 类继承默认是private, struct 默认继承是public C++中的隐藏: 只要派生类中出现和基类一样的函数名,基类中的函数就会被派生类中的函数给隐藏(如果派生类和基类中的函数名 ...

  8. [转帖]Java中重写和重载与多态的关系

    Java中重写和重载与多态的关系 2019-09-05 00:57:41 留下一天今天 阅读数 67  收藏 更多 分类专栏: java进阶之路   版权声明:本文为博主原创文章,遵循CC 4.0 B ...

  9. C++与Java多态的区别

    多态是指用父指针指向不同子类对象时,调用其共有的函数,不同的子类会有不同的行为.虽然C++和Java都具有多态机制,但是他们的实现不同,使用时的效果也会略有不同. 在C++中 普通函数调用:具体调用哪 ...

随机推荐

  1. bzoj 1233: [Usaco2009Open]干草堆tower

    1233: [Usaco2009Open]干草堆tower Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的 ...

  2. MySort

    实验概述: 本次试验的内容:模拟实现Linux下Sort -t : -k 2的功能.参考Sort的实现.提交码云链接和代码运行截图. 截图如下 实验过程 在实验课上真的很崩溃,可以说脑子里一团乱麻,下 ...

  3. linux基础环境搭建(2)

    打开虚拟机,用Xshell连接之前,首先我们要获取IP的地址   先输入获取 IP的命令 ip addr 获取ipifup (网卡名字) #网卡启动ifdown (网卡名字) #网卡关闭 没有获取到的 ...

  4. Codeforces Round #343 (Div. 2) C. Famil Door and Brackets dp

    C. Famil Door and Brackets 题目连接: http://www.codeforces.com/contest/629/problem/C Description As Fami ...

  5. NHibernate 存储过程 第十四篇

    NHibernate也是能够操作存储过程的,不过第一次配置可能会碰到很多错误. 一.删除 首先,我们新建一个存储过程如下: CREATE PROC DeletePerson @Id int AS DE ...

  6. devfs、sysfs、udev介绍

    转:http://www.360doc.com/content/11/1203/09/7378000_169310928.shtml 一.devfs linux下有专门的文件系统用来对设备进行管理,d ...

  7. java接入极光推送

    直接提供工具类, 调用时直接调用其 sendToRegistrationId() 方法 1 import cn.jiguang.common.resp.APIConnectionException; ...

  8. minishift的本地代码构建

    看文档说支持,但实际尝试了下,失败 发现仍然是找github中的代码 找了半天,发现是在目录下有.git的隐含目录,然后copy到其他目录下删除,然后再试,发现仍然失败. 日志看是指定的目录并没有传入 ...

  9. Dockerfile减少构建镜像大小的方法

    这几天基于Dockerfile构建应用需要的特殊的镜像,比如Nginx需要add很多module的,就需要在镜像内编译和做build. 通过Dockerfile构建镜像时,很容易把镜像构建得很大. 从 ...

  10. XSD-学习总结

    1.代码详细分析 <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/X ...