Java类和对象的初始化顺序

发表于:2012-2-29 10:03

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

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

  类装载步骤

  在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

  装载:查找和导入类或接口的二进制数据;

  链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;

  校验:检查导入类或接口的二进制数据的正确性;

  准备:给类的静态变量分配并初始化存储空间;

  解析:将符号引用转成直接引用;

  初始化:激活类的静态变量的初始化Java代码和静态Java代码块。

  其中 初始化(initialization)包含两部分:

  1、类的初始化(initialization class & interface)

  2、对象的创建(creation of new class instances)。

  因为类的初始化其实是类加载(loading of classes)的最后一步,所以很多书中把它归结为“对象的创建”的第一步。其实只是看问题的角度不同而已。为了更清楚的理解,这里还是分开来。

  顺序:

  因为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是:

  类初始化 -> 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句

  下面结合例子,具体解释一下。

  1、类的初始化(Initialization classes and interfaces)

  其实很简单,具体来说有:

  (a)初始化类(initialization of class),是指初始化static field 和执行static初始化块。

  1. public class Demo{   
  2.     //初始化static field,   
  3.     //其中= "initialization static field"又叫做static field initializer  
  4.     private static String str = "initialization static field";   
  5.    
  6.     //初始化块,又叫做static initializer,或 static initialization block  
  7.     static {   
  8.         System.out.println("This is static initializer");   
  9.     }   
  10. }

  btw,有些书上提到static initializer 和 static field initializer 的概念,与之对应的还有 instance initializer 和 instance variable initializer。例子中的注释已经解释了其含义。

  (b)初始化接口(initialization of interface),是指初始化定义在该interface中的field。

  *注意*

  1、initialization classes 时,该class的superclass 将首先被初始化,但其实现的interface则不会。

  initialization classes 时,该class的superclass,以及superlcass的superclass 会首先被递归地初始化,一直到java.lang.Object为止。但initialiazation interface的时候,却不需如此,只会初始化该interface本身。

  2、对于由引用类变量(class field)所引发的初始化,只会初始化真正定义该field的class。

  3、如果一个static field是编译时常量(compile-time constant),则对它的引用不会引起定义它的类的初始化。

  为了帮助理解最后两点,请试试看下面的例子:

  Initialization类

  1. public class Initialization {   
  2.    
  3.     static {   
  4.         System.out.println("Initialization Main class");   
  5.     }   
  6.    
  7.     public static void main(String[] args)  {   
  8.         System.out.println(Sub.y);   
  9.         System.out.println(Sub.x);   
  10.         System.out.println(Sub.z);   
  11.     }   
  12. }

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

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号