疯狂java


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

Java对象初始化顺序


 

  1.父类子类构造函数执行的先后顺序

  public class Test2 {

  public int Field;

  //step 1

  public Test2(){

  Field = 1;

  }

  }

  /*************************************************/

  /**

  * 次类的目的仅是为了验证父类子类构造函数执行的先后顺序

  */

  public class Test3 extends Test2{

  //step 2

  public Test3(){

  Field = 2;

  }

  public static void main(String[] args) {

  Test3 t3 = new Test3();

  System.out.println("对象t3中字段的值是【" + t3.Field + "】");

  /************************************

  * 输出结果

  * 对象t3中字段的值是【2】

  ************************************/

  }

  }

  结论:实例化一个对象,构造的执行顺序是由父类到子类的顺序,即Test2->Test3

  2.构造函数初始化和内联方式初始化

  /**

  * 此类目的仅是为了验证以内联的方式初始化字段和构造函数中初始化的

  * 字段的先后顺序

  *

  * 内联初始化的内联的意思,就是在声明字段的时候同时进行初始化赋值。

  */

  public class Test1 {

  public int Field = 1;//step 1

  /**

  * step 2

  */

  public Test1() {

  Field = 2;

  }

  public static void main(String[] args) {

  Test1 t1 = new Test1();

  System.out.println("对象t1中字段的值是【" + t1.Field + "】");

  /************************************

  * 输出结果

  * 对象t1中字段的值是【2】

  ************************************/

  }

  }

  结论:实例化一个对象会先执行以内联方式初始化字段的代码,然后再去执行构造函数内的内容

  3.静态块和内联方式(静态)初始化

  public class Test4 {

  public static int Field = 1;//step 1

  /**

  * step 2

  */

  static {

  Field = 2;

  }

  public static void main(String[] args) {

  System.out.println("字段Field的值是【" + Field + "】");

  /************************************

  * 输出结果

  * 字段Field的值是【2】

  ************************************/

  }

  }

  结论:内联方式初始化静态字段要先于使用静态块初始化字段

  4.初始化块和初始化块(静态)

  public class Test5 {

  public static int Field;

  //初始化块(静态)

  static {

  Field = 1;

  }

  //初始化块

  {

  Field = 2;

  }

  public static void main(String[] args) {

  System.out.println("字段Field的值是【" + Field + "】");

  /*************************************

  * 输出结果

  * 字段Field的值是【1】

  *************************************/

  }

  }

  结论:初始化块要优先于静态初始化块执行(错误结论)

  总感觉这个结论怪怪的,然后查了一些资料,得知初始化块只有在实例化一个对象的时候才会执行

  public class Test5 {

  public static int Field;

  //初始化块(静态)

  static {

  Field = 1;

  }

  //初始化块

  {

  Field = 2;

  }

  public static void main(String[] args) {

  System.out.println("对象未被实例化之前,Field的值是【" + Field + "】");

  Test5 test5 = new Test5();

  System.out.println("对象被被实例化之后,Field的值是【" + Field + "】");

  //为了验证每次实例化对象都会调用初始化器

  Field = 3;

  System.out.println("给字段Field赋值,Field的值是【" + Field + "】");

  Test5 test5_0 = new Test5();

  System.out.println("再次实例化对象之后,Field的值是【" + Field + "】");

  /*************************************

  *对象未被实例化之前,Field的值是【1】

  *对象被被实例化之后,Field的值是【2】

  *给字段Field赋值,Field的值是【3】

  *再次实例化对象之后,Field的值是【2】

  *************************************/

  }

  }

  为了验证上边提到的红色字体部分正确性,还特意的将Field的值赋值为3并再次实例化 对象

  结论:初始化器只有当被实例化的时候才会执行,并且每次实例化都会执行,静态初始化器有先于初

  始化器执行

  5.面试题一

  public class Test6 {

  public static int i = Test7.j;

  {

  i++;

  }

  static {

  i = 0;

  }

  public Test6() {

  i++;

  }

  }

  /*********************************************/

  public class Test7 extends Test6 {

  public static int j = Test6.i;

  static {

  j++;

  }

  {

  j++;

  }

  }

  /********************************************/

  public class Main {

  public static void main(String[] args) {

  Test7 t7 = new Test7();

  System.out.println("字段I的值是【" + Test6.i + "】");

  System.out.println("字段J的值是【" + Test7.j + "】");

  }

  }

  6.面试题二

  public class Test6 {

  public static int i = Test7.j;

  {

  i++;

  }

  static {

  i = 0;

  }

  public Test6() {

  i++;

  }

  }

  /*********************************************/

  public class Test7 {

  public static int j = Test6.i;

  static {

  j++;

  }

  {

  j++;

  }

  }

  /*********************************************/

  public class Main {

  public static void main(String[] args) {

  Test7 t7 = new Test7();

  System.out.println("字段I的值是【" + Test6.i + "】");

  System.out.println("字段J的值是【" + Test7.j + "】");

  }

  }