黑马程序员技术交流社区

标题: 关于初始化的一些问题<已解决> [打印本页]

作者: 左建飞    时间: 2012-8-4 18:46
标题: 关于初始化的一些问题<已解决>
本帖最后由 左建飞 于 2012-8-6 11:38 编辑
  1. class A//加载子类前会先加载父类。
  2. {
  3.         B b = new B();
  4.         A() //加载时会执行构造函数么?
  5.         {
  6.                 System.out.print("A");
  7.         }
  8.         
  9.         
  10. }

  11. class B
  12. {
  13.         B()
  14.         {
  15.                 System.out.print("B");
  16.         }
  17.         static
  18.         {
  19.                 System.out.print("静态代码块");
  20.         }
  21. }


  22. class C extends A
  23. {
  24.         B b = new B();
  25.         C()
  26.         {
  27.                 //子类的构造函数开头默认会有super();会执行么?
  28.                 System.out.print("C");
  29.         }

  30.         public static void main(String[] args)
  31.         {
  32.                 new C();
  33.         }
  34. }
复制代码
结果是静态代码块BABC,详细的过程是怎样的?
作者: 杜佳瑞    时间: 2012-8-4 18:54
本帖最后由 杜佳瑞 于 2012-8-4 19:08 编辑

这是我总结的:
1,当new一个Zi对象时,首先将Zi.class以及父类文件加载到内存中。

2,执行父类中得static代码块,static成员变量初始化,这两个static代码按顺序执行,然后再执行子类的static代码块和static成员变量。

3,父类中普通成员变量初始化以及构造代码块执行,无优先级之分,顺序如同静态。

4,最后执行父类中构造函数,完毕后才向下执行子类。

5,子类中普通成员变量、代码块、构造函数执行顺序同父类。

首先,创建c对象会执行隐形super(),这时父类就会加载到内存,执行A类构造函数之前,先创建对象b(上面第3、4条),这时候会加载到b类,执行B类中静态代码块(打印静态代码块),再执行构造函数(打印B),最后执行A类的构造函数(打印A),最后在执行C构造函数之前先执行B b = new B();(参考3和4)(因为静态代码块只执行一次这时只打印一次B),最后执行C构造函数(打印C)
有点绕啊 呵呵

作者: 左建飞    时间: 2012-8-4 18:59
好像不小心发了俩一样的问题。怎么办?{:soso_e109:}
作者: 官文昌    时间: 2012-8-4 20:03
首先我们从主函数看:new C();而c函数里面你首先对建了一个B的对象(B b = new B())。而静态代码块在类初始化时便已加载,并且只执行一次,所以首先执行静态代码块(   System.out.print("静态代码块")),然后程序往下执行:这里面有个隐式的super(),程序执行执行类A,首先执行的是类A的构造函数(类只有在使用New调用创建的时候才会被JAVA类装载器装入,创建类实例时,首先按照父子继承关系进行初始化,类实例创建时候,首先初始化块部分先执行,然后是构造方法;然后从本类继承的子类的初始化块执行,最后是子类的构造方法),然后类A里面创建类B的对象,构造函数是随着类的对象的建立而加载了,所以程序执行System.out.print("B");注意:静态代码块只执行一次,最后程序执行子类c的自己的方法。所以结果是:静态代码块BABC
作者: 宫明星    时间: 2012-8-4 21:26
貌似发重了
作者: 尤洋    时间: 2012-8-4 23:01
本帖最后由 尤洋 于 2012-8-5 08:25 编辑
  1. class A//加载子类前会先加载父类。

  2. {

  3.         B b = new B();  //---------------------------------------------------(3)构造代码块 中 创建对象b,执行B类的构造函数,输出B

  4.         A() //加载时会执行构造函数么?

  5.         {

  6.                 System.out.print("A");//------------------------------------(4)继续执行父类构造函数 ,输出A,父类执行完毕,回到子类构造函数

  7.         }        

  8. }


  9. class B
  10. {

  11.         B()
  12.         {

  13.                 System.out.print("B");

  14.         }

  15.         static               //-----------------------------------------------(1)第一步执行.因为静态随类的加载而加载,优先对象而存在。

  16.         {                                                                                                        

  17.                 System.out.print("静态代码块");//---------------------(1)输出   静态代码块

  18.         }

  19. }



  20. class C extends A
  21. {

  22.         B b = new B();//-------------------------------------------------(5)新建b对象,执行B的构造函数,输出B

  23.         C()
  24.         {              

  25.                 System.out.print("C");//--------------------------------(6)执行子类构造函数,输出 C。

  26.         }

  27.         public static void main(String[] args)

  28.         {
  29.                 new C();      //-----------------------------------------(2)main函数进栈,创建C类对象,随着对象建立,要先初始化,执行构造函数
  30.                                                                                         //由于class C extends A    所以要先执行父类的构造代码块 和 构造函数。
  31.         }

  32. }
复制代码

作者: 左建飞    时间: 2012-8-5 22:08
杜佳瑞 发表于 2012-8-4 18:54
这是我总结的:
1,当new一个Zi对象时,首先将Zi.class以及父类文件加载到内存中。

同学,首先执行隐式super()时不会执行syso(“a”)么?还是因为此处的super()跟上面定义的空参数的super()不是一个super呢?
作者: 杜佳瑞    时间: 2012-8-6 10:45
左建飞 发表于 2012-8-5 22:08
同学,首先执行隐式super()时不会执行syso(“a”)么?还是因为此处的super()跟上面定义的空参数的super() ...

C类中构造函数隐式的super就是调用A类中的空参数构造函数,但是在此之前要先初始化A类中的成员变量,这时会会先创建B类的对象,所以先加载B类,这样就会先加载B类中static块,再执行构造函数,完事之后再来执行A类构造函数




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2