Java类中各成员初始化的顺序


了解Java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识。不说太多,直接看下面的例子


class Father

{

  static{

          System. out.println("父类静态代码块初始化" );

  }

  {

          System. out.println("父类代码块初始化" );

  }

  private static String s=print();

  public static String print()

  {

          System. out.println("父类静态方法" );

          return "父类静态成员变量的初始化" ;

  }

  public Father()

  {

          System. out.println("父类无参构造函数初始化完成" );

          show();

  }

  public void show()

  {

          System. out.println("父类show()方法" );

  }

}

class Son extends Father

{

  static{

          System. out.println("子类静态代码块初始化" );

  }

  {

          System. out.println("子类代码块初始化" );

  }

  private static  int i=1;

  private String s="子类私有成员变量" ;

  public void show()

  {

          System. out.println("子类show()方法:i=" +i);

  }

  public Son()

  {

          System. out.println("子类构造函数初始化完成" );

          show();

  }

}

public class TestClassLoadSeq {

        public static void main(String[] args)

      {

              new Son();

      }

}

输出结果:

父类静态代码块初始化
父类静态方法
子类静态代码块初始化
父类代码块初始化
父类无参构造函数初始化完成
子类show()方法:i=1
子类代码块初始化
子类构造函数初始化完成
子类成员变量初始化完成:s=子类私有成员变量
子类show()方法:i=1

从结果可以看出类中各成员初始化的顺序是:

1.如果类中存在继承关系(像 Son 继承 Father)  则首先会初始化导出类(Son)的基类(Father),然后再是导出类

2.在基类首先会初始化静态 的东西  静态块>静态变量  而且只初始化一次 (因为静态的东西都是跟着类的加载而加载的)

3.随后就是初始化导出类的静态东西  跟基类的静态初始化一样(同上)

4.初始化基类无参构造器(调用有参就初始化有参构造器)

5.初始化导出类无参构造器(注意:导出类的成员变量和代码块都是是比构造函数的初始化要早。。看输出结果可知)

在上面输出结果大家可能会看到在基类中的构造器中调用了show() 方法,这样的输出可能不奇怪,我现在改一下。

class Father
{
          private static String s= print();
 
  static{
          System. out.println("父类静态代码块初始化" );
  }
  {
          System. out.println("父类代码块初始化" );
  }
  public static String print()
  {
          System. out.println("父类静态方法" );
          return "父类静态成员变量的初始化" ;
  }
  public Father()
  {
          System. out.println("父类无参构造函数初始化完成" );
          show();
  }
  public void show()
  {
          System. out.println("父类show()方法" );
  }
}
class Son extends Father
{
  static{
          System. out.println("子类静态代码块初始化" );
  }
  {
          System. out.println("子类代码块初始化" );
  }
  private int i =1;
  private String s="子类私有成员变量" ;
  public void show()
  {
          System. out.println("子类show()方法:i=" +i);
  }
  public Son()
  {
          System. out.println("子类构造函数初始化完成" );
          System. out.println("子类成员变量初始化完成:s=" +s);
          show();
  }
}
public class TestClassLoadSeq {
        public static void main(String[] args)
      {
              new Son();
      }
 
}

输出结果:

子类静态代码块初始化
父类代码块初始化
父类无参构造函数初始化完成
子类show()方法:i=0
子类代码块初始化
子类构造函数初始化完成
子类成员变量初始化完成:s=子类私有成员变量
子类show()方法:i=1

可以看出跟上面的代码没有什么不同,唯一的不同就是我把导出类中的静态成员变量i 变成了成员变量i,可以看出结果是截然不同,现在的结果是:0

原因:因为上面的静态成员变量是跟着类的加载而初始化的  所以结果是1  而下面的是 成员变量又因为现在还在基类构造器中所以导出类中的成员变量还没有得到初始化  所以是0

所以上面的初始化顺序不够完整,现在补全下:

首先jvm加载类时 会对每个对象的默认初始化 为0  ,对通过组合方式的引用类型 默认初始化为 null

总结:

java中首先初始化基类在初始化导出类(有多少个基类初始化多少个)

如果那里有错误希望大家帮忙提出了大家一起学习(自己也在学习中。。。。)。

提示:  java中的各成员初始化的顺序是非常重要的,很好的掌握对以后的学习非常有帮助

本文永久更新链接地址

相关内容