zoukankan      html  css  js  c++  java
  • 8.1动态连接和解析

    从程序员的角度来看,理解Java体系结构最重要的方面之一就是连接模型。前几章曾讲过, Java的连接模型允许用户自行设计类装载器,这样以来就可以在运行时定制地扩展用户的程序。 通过用户自定义的类装载器,你的程序可以装载在编译时并不知道或许尚未存在的类或者接口, 并动态连接它们。

    驱动Java连接模型的引擎是解析过程。前一章描述了类生命周期中的各个阶段,但是没有深 究装载和解析的细节。这一章深人研究装载和解析的细节,并展示解析过程是如何和动态扩展 相得益彰的。本章包括连接模型的概览,常量池解析,方法表,并展示了如何编写和使用类装 载器,而且还给出了几个例子。

    8.1动态连接和解析

    当编译一个Java程序的时候,会得到程序中每个类或者接口的独立的class文件。虽然独立的 文件看上去毫无关联,实际上它们之间通过接口(harbor)符号互相联系,或者与Java API的 class文件相联系。当运行程序的时候,Java虚拟机装载程序的类和接口,并且在动态连接的过程 中把它们互相勾连起来。在程序运行中,Java虚拟机内部组织了一张互相连接的类和接口的网。

    class文件把它所有的引用符号保存在一个地方——常量池。每一个class文件有一个常量池, 每一个被Java虚拟机装载的类或者接口都有一份内部版本的常量池,被称作运行时常量池。运行 时常量池是一个特定于实现的数据结构,数据结构映射到class文件中的常量池。因此,当一个类型被首次装载时,所有来自于类型的符号引用都装载到了类型的运行时常量池。

    在程序运行的某些时刻,如果某个特定的符号引用将要被使用,它首先要被解析。解析过程就是根据符号引用查找到实体,再把符号引用替换成一个直接引用的过程。因为所有的符号引用都保存在常量池中,所以这个过程常被称作常量池解析。

    在第6章中描述过,常量池按照一系列项组织。每一项拥有一个惟一的索引,很像数组元素。 符号引用是可以出现在常量池中的一种项目。使用符号引用的Java虚拟机指令指定位于常量池中 的符号引用的索引。比如,getstatic操作码 < 它把一个静态字段的值压入找中)在字节码流中会 跟有一个常量池索引。常量池中指定索引指向的人口,是一个CONSTANT_Fieldref_info人口, 它显示出这个字段所在类的全限定名以及字段的名字和类型。

    记住,Java虚拟机为每一个装载的类和接口保存一份独立的常量池。当一条指令引用常量池 中的第5个元素的时候,它指向的是当前类的常量池中的第5个元素,即定义Java虛拟机当前正执行的方法的类。
    来自相同或不同方法中的几条指令,可能指向同一个常量池人口,但是每一个常量池入口 都只被解析一次。当符号引用被一条指令解析过后,来自其他指令的访问该符号引用的后续尝 试会认为这项工作已经完成,都使用第一次解析出的直接引用结果。

    连接不仅仅包括把符号引用替换成直接引用,还包括检查正确性和权限。在第7章曾介绍过, 检查符号引用的存在性和访问权限(全面验证阶段的一个方面)就是在解析的时候完成的。比 如,当Java虚拟机把getstatic指令解析为其他类中的字段时,Java虚拟机会检杳确认是否符合下 列条件:

    •那个其他类存在。

    •该类有权访问那个其他类。

    •那个其他类中存在名字相符的字段。

    •那个字段的类型和期望的类型相符(对一个字段的符号引用包含了字段类型)。

    •本类有权访问那个字段。

    •那个字段的确是一个静态类变量,而不是一个实例变量。

    如果这些检查中的任何一项失败了,都会抛出一个错误,解析也就失败。否则,这个符号 引用被直接引用替换,解析则成功了。

    在第7章曾描述过,不同的Java虚拟机实现允许在程序执行的不同时间进行解析。实现可以 选择预先解析所有的符号引用,从初始类开始,到后续的各个类,直到所有的符号引用都被解 析了。在这种情形中,程序在它的main ()方法尚未被调用时就已经完全连接了,这种方法被称为早解析。另外一种方式是,实现可以在访问每一个符号引用的最后一刻才去解析它。在这 种情形中,Java虚拟机只会在执行程序第一次用到这个符号引用的时候才去解析它,这种方法被 称为迟解析。实现时也可以选择两种极端情况之间的折衷解析策略。

    虽然Java虚拟机的实现有选择何时解析符号引用的自由,但不管怎样,都应该给外界一个迟 解析的印象。对于特定的Java虚拟机来说,不管何时执行解析,都在程序执行过程中第一次实际 试图访问一个符号引用的时候才抛出错误。用这种方式,对用户来说看上去都是迟解析。如果Java虚拟机使用早解析,在早解析的过程中发现某个dass文件无法找到,它不会抛出对应的错误, 直到后来程序实际汸问这个class文件中的某些东西时才抛出错误。如果程序不使用这个类,错误永远不会被抛出。

  • 相关阅读:
    昇腾AI处理器软件栈--任务调度器(TS)
    [转]shopnc 版权问题
    关于对接诸葛IO 解决的问题
    Mysql中like查询中存在反斜杠的解决方法
    关于TP,PHP和shopnc 的cookie
    TypeError: document.getElementById(…).submit is not a function解决
    关于图片上传的 相对路径出现问题
    Android 通讯录
    关于kindedit和 Uedit后者兼容前者
    Handler机制
  • 原文地址:https://www.cnblogs.com/mongotea/p/11979569.html
Copyright © 2011-2022 走看看