疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java入门初始化顺序


 

   

  初始化顺序的规则

  1.在一个类的对象实例化时,成员变量首先初始化,然后才调用构造器,无论书写顺序。如果调用构造器前,没有显式初始化,那么会赋默认值。

  这样做法的原因可以理解为:构造器执行时可能会用到一些成员变量的初值。

  2.static变量早于所有其他的类成员变量初始化,同样无论书写顺序。但是static变量仅在所在类第一次被使用时初始化一次。

  3.基类构造器总是在导出类的构造过程中被调用,而且按照继承层级逐渐向上链接(调用顺序则是从基类开始向下)。可以理解为,这么做的逻辑关系是在一个类构建时可能会用到其父类的成员、方法。在清理时顺序相反。

  4.成员的初始化方法(包括基本数据类型的赋值)在基类构造器调用之后才会被调用。最初时,分配给对象的存储空间初始化二进制的零。

  

  class Bowl {

  Bowl(int marker) {

  System.out.println("Bowl(" + marker + ")");

  }

  }

  class Cupboard {

  Bowl bowl1 = new Bowl(3);

  static Bowl bowl2 = new Bowl(1);

  int i;

  static int j = 5;

  Cupboard() {

  System.out.println("i:" + i);

  bowl4 = new Bowl(j);

  j = 6;

  }

  Bowl bowl3 = new Bowl(4);

  static Bowl bowl4 = new Bowl(2);

  }

  public class ParaInitialization {

  public static void main(String args[]) {

  new Cupboard();

  new Cupboard();

  }

  }

  复制代码

  输出及对应注释:

  Bowl(1)     //第一个static变量

  Bowl(2)     //第二个static变量

  Bowl(3)     //第一个对象的第一个非static成员变量

  Bowl(4) //第一个对象的第一个非static成员变量

  i:0       //未显示初始化的成员变量

  Bowl(5)     //更改static变量的值

  Bowl(3)     //第二个对象的第一个非static成员变量

  Bowl(4)     //第二个对象的第二个非static成员变量

  i:0

  Bowl(6)

  例二是一个演示第3条规则的简单示例。

  复制代码

  class A {

  A() {

  System.out.println("A");

  }

  }

  class B extends A {

  B() {

  System.out.println("B");

  }

  }

  class C extends B {

  C() {

  System.out.println("C");

  }

  }

  public class hrt {

  public static void main(String args[]) {

  new C();

  }

  }

  复制代码

  输出

  A

  B

  C

  例三用于演示规则4。调用父类构造器时,构造器中的方法被子类方法覆盖。

  复制代码

  class Glyph {

  void draw() {

  System.out.println("Glyph.draw(");

  }

  Glyph() {

  System.out.println("Glyph() before draw()");

  draw();

  System.out.println("Glyph() after draw()");

  }

  }

  class RoundGlyph extends Glyph {

  int radius = 1;

  RoundGlyph(int r) {

  radius = r;

  System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);

  }

  void draw() {

  System.out.println("RoundGlyph.draw(), radius = " + radius);

  }

  }

  public class PolyConstructors {

  public static void main(String[] args) {

  new RoundGlyph(5);

  }

  }

  复制代码

  这么多条规则,记起来实在让人头大。将它们按顺序编排会易读很多。

  对象初始化顺序,如果有对应成员/父类的才执行对应条目:

  1.将分配给对象的存储空间初始化为二进制的零;

  2.调用基类构造器,从最顶层/根的基类开始;

  3.按照声明的顺序,使用直接的赋值或者初始化方法,先依次初始化static变量,再依次初始化非static变量;

  4.调用本对象所属类的构造器。