



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java中,在调用类的静态成员,或新建该类的对象等之前,类一定要先装入Java虚拟机中,这是勿庸置疑的。但虚拟机怎样把类装载进来的呢?要经过三步:装载(Load),链接(Link),初始化(Initializ)。其中链接又可分为校验(Verify),准备(Prepare),解析(Resolve)三步。一、装载(Load)ClassLoader就是用来装载的。通过指定的className,找到二进制码,生成Class实例,放到JVM中。ClassLoader从顶向下分为Bootstrap ClassLoader、Extension ClassLoader、System ClassLoader以及User-Defined ClassLoader(分叉,可以多个)。如下图。这是Tomcat装载器的例子:装载过程从源码清析可见:protected synchronized Class loadClass(String name, boolean resolve)throws ClassNotFoundException/ 先检查是否已被当前ClassLoader装载。Class c = findLoadedClass(name);if (c = null) try if (parent != null) / 如果没被当前装载,则递归的到父中装载。c = parent.loadClass(name, false); else / 装载器树已到顶,还没找到的话就到Bootstrap装载器中找。注意:虽然Bootstrap是所有加载器的根,但它是C+实现的,不可能放到子的parent中,因此,第二层装载器是所有的根了。c = findBootstrapClass0(name); catch (ClassNotFoundException e) / 如果祖先都无法装载,则用当前的装载。子类可在findClass方法中调用defineClass,把从自定义位置获得的字节码转换成Class。c = findClass(name);if (resolve) / Links the specified class.resolveClass(c);/ 注return c;注:1. resolveClass(c)方法的注释是链接类,而不只是解析,从该即可看出。调用resolveClass时语义上是去链接,是否真的链接了我不是很清楚,但可以肯定的是没有初始化。当A类中有static B b=new B()时,最晚会在初始化时去装载B。如果改成static B b=null,那么把B.class删掉后,即使A已经链接,初始化过了,但也不会报错,也就是A所引用的B类没有被加载过。解析时难道没有真的去装入它所引用的B类?还是链接时,没有执行解析的步骤? 问题的关键就是 1.对“解析”的理解,解析时是否会去装载B类?2. JVM在链接时是否执行了解析?(毕竟有资料说,解析是可选步骤)二、链接链接就是把load进来的class合并到JVM的运行时状态中。链接是三个阶段中最复杂的一个。可以把它分成三个主要阶段: 校验。对二进制字节码的格式进行校验,以确保格式正确、行为正确。 准备。准备类中定义的字段、方法和实现接口所必需的数据结构。比如会为类中的静态变量赋默认值(int等:0, reference:null, char:u0000)。 解析。装入类所引用的其他所有类。可以用许多方式引用类: 超类 接口 字段 方法签名 方法中使用的本地变量三、初始化Initialization of a class consists of executing its static initializers and the initializers forstaticfields (class variables) declared in the class. Initialization of an interface consists of executing the initializers for fields (constants) declared there.类的初始化包括:执行静态区块和静态方法的初始化。比如下面这两种代码都会被执行,包括new B()。static.static B b=new B();接口中不允许有static initializer(也就是static.),所以对于接口,只会执行静态字段的初始化。初始化前,装载,链接一定已经执行过!类初始化前,它的直接父类一定要先初始化(递归),但它实现的接口不需要先被初始化。类似的,接口在初始化前,父接口不需要先初始化。什么情况下,类的初始化会被触发?A class or interface typeTwill be initialized immediately before the first occurrence of any one of the following: Tis a class and an instance ofTis created. Tis a class and a static method declared byTis invoked. A static field declared byTis assigned. A static field declared byTis used and the field is not a constant variable(4.12.4). Tis a top-level class, and anassertstatement(14.10)lexically nested withinTis executed.当使用类的字段时,即便可以通过子类或子接口访问该字段,但只有真正定义该字段的类会被触发初始化。如下例。class Super static int taxi = 1729; class Sub extends Super static System.out.print(Sub ); class Test public static void main(String args) System.out.println(Sub.taxi);只会输出“1729”,不会输出Sub,也就是说,Sub其实没有被初始化。四、Class.forName()与ClassLoader.loadClass()这两方法都可以通过一个给定的类名去定位和加载这个类名对应的 java.long.Class 类对象,区别如下:1. 初始化Class.forName()会对类初始化,而loadClass()只会装载或链接。可见的效果就是类中静态初始化段及字节码中对所有静态成员的初始工作的执行(这个过程在类的所有父类中递归地调用). 这点就与ClassLoader.loadClass()不同. ClassLoader.loadClass()加载的类对象是在第一次被调用时才进行初始化的。你可以利用上述的差异. 比如,要加载一个静态初始化开销很大的类, 你就可以选择提前加载该类(以确保它在classpath下), 但不进行初始化, 直到第一次使用该类的域或方法时才进行初始化2. 类加载器可能不同Class.forName(String) 方法(只有一个参数), 使用调用者的类加载器来加载, 也就是用加载了调用f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 谈礼貌课件教学课件
- 诺贝尔瓷砖产品知识培训课件
- 2025年建筑工地保安兼职服务合同范本
- 2025版森林资源承包管理与利用合同
- 2025年度综合交通枢纽用地土地平整施工合同
- 2025年度居间合同范本:专业居间服务协议
- 2025版皮毛原料绿色采购与供应链管理合同
- 2025版消防水电工程消防安全检测服务合同
- 2025版托盘制造企业产品认证与质量管理体系合同
- 2025版挖掘机操作人员培训及考核合同范本
- 化学工程与工艺专业人才培养方案
- 《家庭营养配餐》课件
- 产后恢复-中级-1738220692478
- 二零二五版森林抚育项目苗木种植及管护合同2篇
- 药物作用机理创新-洞察分析
- 毕业设计(论文)-口腔助手微信小程序的设计与实现
- ICH《M10:生物分析方法验证及样品分析》
- 电力金具选型手册输电线路金具选型
- 初中开学第一课安全课件
- 2025年企业知识产权管理高效执行方案全面贯标体系实操模板集锦
- 鼻咽通气管日常护理
评论
0/150
提交评论