黑马程序员技术交流社区

标题: 这个代码的执行顺序是怎样的啊,绕晕了 [打印本页]

作者: 焚雨成灰    时间: 2014-3-21 20:36
标题: 这个代码的执行顺序是怎样的啊,绕晕了
本帖最后由 焚雨成灰 于 2014-3-21 21:19 编辑
  1. class Demo {
  2.         public static void main(String[] args) {
  3.                 new C();
  4.                 new C(123);
  5.         }
  6. }                                                        
  7. class A {
  8.         static {
  9.                 System.out.println(1);
  10.         }
  11.         A() {
  12.                 System.out.println(2);
  13.         }
  14.         A(int i) {
  15.                 this();
  16.                 System.out.println(3);
  17.         }
  18. }
  19. class B extends A {
  20.         static{
  21.                 System.out.println(4);
  22.         }
  23.         B(){
  24.                 super(123);
  25.                 System.out.println(5);
  26.         }
  27.         B(int i) {
  28.                 this();
  29.                 System.out.println(6);
  30.         }
  31. }

  32. class C extends B {

  33.         static {
  34.                 System.out.println(7);
  35.         }
  36.         C() {
  37.         super(123);
  38.                 System.out.println(8);
  39.         }
  40.         C(int i) {
  41.                 super();
  42.                 System.out.println(9);
  43.         }
  44. }
复制代码
结果是这个:14723568 2359 。  147之后就不知道程序怎么走了:)

作者: 青木郎    时间: 2014-3-21 20:52
本帖最后由 青木郎 于 2014-3-21 21:02 编辑

顺序就是先加载父类静态代码块,在加载自己的静态代码块,之后加载父类的的构造函数new C();
所以会147,之后父类(A)构造器,2-->B的构造器{super(123);}--->3,-->5--->C的构造器C() {
    super(123);--->6--->8
new C(123);
同理,因为静态代码块直接在一次,所以没有147
A构造器2-->B构造器{super(123)}--->3-->5自己的构造器-->9

作者: 安辉林    时间: 2014-3-21 21:04
程序一加载,所有静态代码块会加载进内存,所以147执行,我给你一个new C();这句代码的分析流程图,后面的你就清楚了,图上画的有点多,希望能帮到你

图片1.png (111.37 KB, 下载次数: 26)

图片1.png

作者: yanzhendong    时间: 2014-3-21 21:17
楼主你好,程序的执行是这样的:在main()函数中new 了一个C对象,因C对象继承自B,要创建C首先要创建B,而B对象继承自A,要创建B首先要创建A,所以A中的构造块最先执行,然后是B中的构造块,然后是C中的构造块,构造块执行完毕后就该执行构造函数了,因C()中调用了其父类的B(int i )构造函数,B(int i )中又调用了自身的B()函数,B()函数又调用了父类A(int i ),A(int i )又调用了A()函数,所以第四个数是2,接着按照以上的函数调用顺序往回递归即可,依次是323568。对于第二个new C(123),因第一个对象已经执行了构造代码块,所以第二个对象不会再执行构造块,其函数调用栈是这样的:C(123)=>B()=>A(123)=>A();根据这个顺序往回递归即为结果。希望能解决楼主的疑问
作者: 焚雨成灰    时间: 2014-3-21 21:19
安辉林 发表于 2014-3-21 21:04
程序一加载,所有静态代码块会加载进内存,所以147执行,我给你一个new C();这句代码的分析流程图,后面的 ...

:o幸苦啦
作者: 欢欢    时间: 2014-3-21 21:24
本帖最后由 欢欢 于 2014-3-21 23:21 编辑

代码里加点内容,这样比较好看:
  1. class Test {
  2.         public static void main(String[] args) {
  3.                 new C();
  4.                 new C(123);
  5.         }
  6. }                                                        
  7. class A {
  8.         static {
  9.                 System.out.println("A.satic:"+1);
  10.         }
  11.         A() {
  12.                 System.out.println("A():"+2);
  13.         }
  14.         A(int i) {
  15.                 this();
  16.                 System.out.println("A(i):"+3);
  17.         }
  18. }
  19. class B extends A {
  20.         static{
  21.                 System.out.println("B.static:"+4);
  22.         }
  23.         B(){
  24.                 super(123);
  25.                 System.out.println("B():"+5);
  26.         }
  27.         B(int i) {
  28.                 this();
  29.                 System.out.println("B(i):"+6);
  30.         }
  31. }

  32. class C extends B {

  33.         static {
  34.                 System.out.println("C.static:"+7);
  35.         }
  36.         C() {
  37.         super(123);
  38.                 System.out.println("C():"+8);
  39.         }
  40.         C(int i) {
  41.                 super();
  42.                 System.out.println("C(i):"+9);
  43.         }
  44. }
复制代码
静态代码块,类一加载,只执行一次。
作者: 安辉林    时间: 2014-3-21 21:43
焚雨成灰 发表于 2014-3-21 21:19
幸苦啦

客气了,我刚开始学的时候也是什么都不会,慢慢就好了,别着急
作者: luoyilan222    时间: 2014-3-21 21:54
在eclipse或myEclipse 中debug 比任何人给你讲都好
作者: 俞帅明    时间: 2014-4-2 21:59
本帖最后由 俞帅明 于 2014-4-2 22:02 编辑

静态代码块构造代码块
父类构造函数
本类构造函数


作者: syusikoku    时间: 2014-4-3 15:44
我帮你分析出来了。我是以new C(123);为打印进行的分析。建议你如果没有分析经验的话。先不要打印这么多。单一的进行分析这样你会感觉好点。下面是我的分析。稍候我会把图片上传上来。
1 所有的静态代码块随着类的加载而加载
2 先调用C的有参的构造方法。因为C要先调用父类的
有参的构造方法,然后在B中又是调用了父类的有参
的构造方法。然后B调用了A的有参的构造方法。A中
调用了A的无参的构造方法。
调用的顺序是从下往上的。打印的时候是从上往下打印的。
因为是父类要先打印嘛。
图片如下:

分析.PNG (116.79 KB, 下载次数: 42)

分析

分析





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