转:Java动态绑定的内部实现机制

JAVA虚拟机调用一个类方法时,它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当虚拟机调用一个实例方法时,它会基于对象实际 的类型(只能在运行时得知)来选择所调用的方法,这就是动态绑定,是多态的一种。动态绑定为解决实际的业务问题提供了很大的灵活性,是一种非常优美的机 制。

1 JAVA对象模型

JAVA虚拟机规范并没有规定JAVA对象在堆里是如何表示的。对象的内部表示也影响着整个堆以及垃圾收集器的设计,它由虚拟机的实现者决定。

JAVA对象中包含的基本数据由它所属的类及其所有超类声明的实例变量组成。只要有一个对象引用,虚拟机就必须能够快速地定位对象实例的数据。另外,它也 必须能通过该对象引用访问相应的类数据(存储于方法区的类型信息),因此在对象中通常会有一个指向方法区的指针。当程序在运行时需要转换某个对象引用为另 外一种类型时,虚拟机必须要检查这种转换是否被允许,被转换的对象是否的确是被引用的对象或者它的超类型。当程序在执行instanceof操作时,虚拟 机也进行了同样的检查。所以虚拟机都需要查看被引用的对象的类数据。

不管虚拟机的实现使用什么样的对象表示法,很可能每个对象都有一个方法表因为方法表加快了调用实例方法时的效率。但是JAVA虚拟机规范并未要求必须使用方法表,所以并不是所有实现中都会使用它。

下面是一种JAVA对象的内存表示:

JAVA对象内存模型

方法数据存放在类的方法区中,包含一个方法的具体实现的字节码二进制。方法指针直接指向这个方法在内存中的起始位置,通过方法指针就可以找到这个方法。

2 动态绑定内部机制

方法表是一个指向方法区中的方法指针的数组。方法表中不包含static、private等静态绑定的方法,仅仅包含那些需要动态绑定的实例方法。

在方法表中,来自超类的方法出现在来自子类的方法之前,并且排列方法指针的顺序和方法在class文件中出现的顺序相同,这种排列顺序的例外情况是,被子类的方法覆盖的方法出现在超类中该方法第一次出现的地方。

例如有超类Base和子类Derive:

  1. public class Base
  2. {
  3. public Base()
  4. {
  5. }
  6. public void test()
  7. {
  8. System.out.println( "int Base" );
  9. }
  10. public void print()
  11. {
  12. }
  13. }
  14. public class Derive extends Base
  15. {
  16. public Derive()
  17. {
  18. }
  19. public void test()
  20. {
  21. System.out.println( "int Derive" );
  22. }
  23. public void sayHello()
  24. {
  25. }
  26. public static void main( String[] args )
  27. {
  28. Base base = new Derive();
  29. base.test();
  30. }
  31. }

上例中的Base和Derive的方法表如下:

在这个例子里,test()方法在Base和Derive的方法表中都是同一个位置-位置1。在Base方法表中,test()指针是Base的test()方法内存地址;而在Derive方法表中,方法表的位置1放置的是Derive的test()方法内存地址。

当JAVA虚拟机执行base.test()时,通过base引用可以找到base所指向的实际对象的内存位置,现在虚拟机不知道base引用的实际对象 是Base还是Derive。但是根据上面的对象内存模型,虚拟机从对象内存中的第一个指针“特殊结构指针”开始,可以找到实际对象的类型数据和 Class实例,这样虚拟机就可以知道base引用的实际对象是Derive对。为了执行test(),虚拟机需要找到test()的字节码,方法的字节 码存放在方法区中。虚拟机从对象内存中的第一个指针“特殊结构指针”开始,搜寻方法表的位置1,位置1指向的test()方法是Derive类的 test()方法,这就是JAVA虚拟机将要执行的test()的字节码。现在,虚拟机知道了调用的实际对象是Derive对象,调用的实际test() 方法是Derive类的test()方法,所以JAVA虚拟机能够正确执行-调用base引用的实际对象的方法而不是base引用本身的方法。

这是动态绑定的一种实现方式,根据不同的JAVA虚拟机平台和不同的实际约束,动态绑定可以有不同的内部实现机制。

转:Java 动态代理的内部实现机制(大体意思正确,写的还行的一篇文章)的更多相关文章

  1. Java 动态代理及AOP实现机制

    AOP实现机制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面编程AOP包括切面(aspect).通 ...

  2. java动态代理的基本思想以及简单的实现

    代理模式 本人参考于代理模式及Java实现动态代理  不作为商业用途,只是借鉴于其思路.侵权即删. 原理:给某个对象提供一个代理对象,并且由代理对象控制原对象的访问,即不直接操控原对象,而是通过代理对 ...

  3. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  4. [转]Java 动态代理机制分析及扩展

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  5. 深入理解 Java 动态代理机制

    Java 有两种代理方式,一种是静态代理,另一种是动态代理.对于静态代理,其实就是通过依赖注入,对对象进行封装,不让外部知道实现的细节.很多 API 就是通过这种形式来封装的. 代理模式结构图(图片来 ...

  6. Java动态代理机制研读

    java动态加载类(反射机制) /*MyClass.java*/ public class MyClass { public int id; public String name; public in ...

  7. Java动态代理的实现机制

    一.概述 代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类负责为委托类预处理消息,过滤消息并转发消息以及进行消息被委托类执行后的后续处理.为了保持行为的一致性,代理类和 ...

  8. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  9. Java 动态代理机制分析及扩展,第 1 部分

    Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...

随机推荐

  1. Java - Java 中的三种 ClassLoader

    1.虚拟机类加载器(称为“bootstrap class loader”),它本身没有父类加载器,它负责加载虚拟机的内置类,由于它是用C.C++写的,所以Java无法拿到其class文件,返回的都是空 ...

  2. Centos 6版本Device eth0 does not seem to be present,delaying initialization.故障处理

    1.1  故障现象 2019年06月14日晚上,公司项目组说有台业务服务器连接不上,比较着急,我通过vpn拨入的方式远程登录到管理控制台查看发现网卡没有获取到IP地址,我尝试重启来重新启动,重启的时候 ...

  3. 三 python并发编程之多线程-理论

    一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...

  4. 二 python并发编程之多进程-理论

    一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...

  5. pycharm配置Git托管

    利用Pycharm和github管理代码转载https://www.cnblogs.com/feixuelove1009/p/5955332.html git教程--廖雪峰git教程  转载https ...

  6. 字符编码笔记:ASCII、Unicode和UTF-8

    1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte). ...

  7. Android stadio 电脑连上手机可以识别,但是连不上Android stadio

    原来是因为电脑没有装Android 手机驱动,我电脑刚装了系统. 很多驱动没有装.我有一个联想驱动管理,提示我装Android手机驱动.装完之后,就可以识别到手机了. 如果你的手机在电脑不识别,那么装 ...

  8. 常用Style

    有些输入框什么的,字数限制什么的style,ceb为我们写好了.我感觉,每个app的style都是很有用的一个东西. <?xml version="1.0" encoding ...

  9. SVM python小样例

    SVM有很多种实现,但是本章只关注其中最流行的一种实现,即序列最小化(SMO)算法在此之后,我们将介绍如何使用一种称为核函数的方式将SVM扩展到更多的数据集上基于最大间隔的分割数据优点:泛化错误率低, ...

  10. leetcode 【 Find Minimum in Rotated Sorted Array 】python 实现

    题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7  ...