关闭

分析Java类加载全过程

发表于:2012-11-08 09:32

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

  今天去涉猎了一下类的加载的过程,现在也总结一下:

  一个java文件从被加载到被卸载这个生命过程,总共要经历4个阶段:

  加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载

  其中加载(除了自定义加载)+链接的过程是完全由jvm负责的,什么时候要对类进行初始化工作(加载+链接在此之前已经完成了),jvm有严格的规定(四种情况):

  1、遇到new,getstatic,putstatic,invokestatic这4条字节码指令时,加入类还没进行初始化,则马上对其进行初始化工作。其实就是3种情况:用new实例化一个类时、读取或者设置类的静态字段时(不包括被final修饰的静态字段,因为他们已经被塞进常量池了)、以及执行静态方法的时候。

  2、使用java.lang.reflect.*的方法对类进行反射调用的时候,如果类还没有进行过初始化,马上对其进行。

  3、初始化一个类的时候,如果他的父亲还没有被初始化,则先去初始化其父亲。

  4、当jvm启动时,用户需要指定一个要执行的主类(包含static void main(String[] args)的那个类),则jvm会先去初始化这个类。

  以上4种预处理称为对一个类进行主动的引用,其余的其他情况,称为被动引用,都不会触发类的初始化。下面也举了些被动引用的例子:

  1. /** 
  2.  * 被动引用情景1 
  3.  * 通过子类引用父类的静态字段,不会导致子类的初始化 
  4.  * @author volador 
  5.  * 
  6.  */ 
  7. class SuperClass{  
  8.     static{  
  9.         System.out.println("super class init.");  
  10.     }  
  11.     public static int value=123;  
  12. }  
  13. class SubClass extends SuperClass{  
  14.     static{  
  15.         System.out.println("sub class init.");  
  16.     }  
  17. }  
  18. public class test{  
  19.     public static void main(String[]args){  
  20.         System.out.println(SubClass.value);  
  21.     }  
  22.       
  23. }

  输出结果是:super class init。

  1. /** 
  2.  * 被动引用情景2 
  3.  * 通过数组引用来引用类,不会触发此类的初始化 
  4.  * @author volador 
  5.  * 
  6.  */ 
  7. public class test{  
  8.     public static void main(String[] args){  
  9.         SuperClass s_list=new SuperClass[10];  
  10.     }  
  11. }

  输出结果:没输出

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号