黑马程序员技术交流社区

标题: 子类对象实例化过程中的构造代码块问题 [打印本页]

作者: jkenny    时间: 2014-2-15 17:00
标题: 子类对象实例化过程中的构造代码块问题
以下代码执行后的结果是:
(1)Person static10
(2)Student static99
{}Person
(3)Persion100lishi
{}Student
(4)Student100lishi
(5)Student名
问:执行Person的构造代码块({}Person)后为什么是执行父类的构造方法((3)Persion100lishi),而不是执行子类的构造代码块({}Student)?
如果是因为子类执行了super(age);而先去执行父类中的构造方法((3)Persion100lishi),那么执行完后为什么不是回来执行子类的构造函数((4)Student100lishi)而是又先执行了子类中的构造代码块({}Student);,而且构造代码块不是优先与构造函数执行的吗?
  1. class ExtendsTest
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Student s=new Student(100,"名");
  6.         }
  7. }
  8. //----------------------------------------------Person.class
  9. class Person
  10. {
  11.         public static int age=10;
  12.         String name="lishi";
  13.         //静态代码块
  14.         static
  15.         {
  16.                 System.out.println("(1)Person static"+age);
  17.         }
  18.         //构造代码块
  19.         {
  20.                 System.out.println("{}Person");
  21.         }
  22.         //构造方法
  23.         public Person(int age)
  24.         {
  25.                 this.age=age;
  26.                 System.out.println("(3)Persion"+age+name);
  27.         }

  28. }
  29. //---------------------------------------------Student.class
  30. class Student extends Person
  31. {
  32.         static int ss=99;
  33.         //静态代码块
  34.         static
  35.         {
  36.                 System.out.println("(2)Student static"+ss);
  37.         }
  38.         //构造代码块
  39.         {
  40.                 System.out.println("{}Student");
  41.         }
  42.         //构造方法
  43.         Student(int age)
  44.         {
  45.                 super(age);
  46.                 System.out.println("(4)Student"+age+name);
  47.         }
  48.         Student(int age,String name)
  49.         {
  50.                 this(age);
  51.                 this.name=name;
  52.                 System.out.println("(5)Student"+name);
  53.         }


  54. }
复制代码

作者: 疲劳的小马    时间: 2014-2-15 19:48
楼主你好,小弟也是才初学的Java,也刚学到这一块不久,不知道想法对不对……我是这样理解的:在类初始化时,先执行内存中的静态方法区部分吧,初始化类时先执行父类的静态代码块,如果子类也有静态代码块,执行完父类后就执行子类的静态代码块,方法区执行完,继续初始化父类,执行父类的 构造代码块 构造函数等,父类初始化完毕后再执行子类的构造代码块 构造函数等。所以本例中执行父类Person的构造代码块({}Person)后,执行父类的构造方法((3)Persion100lishi),然后再执行子类的构造代码块({}Student),构造函数。
作者: 廉伟杰    时间: 2014-2-15 20:30
其实这种不知道执行顺序问题,最简单的方法就是调试单步运行一下,就知道运行程序

要是理解的话是这样理解的
首先静态代码块是优先于主方法执行,优先于构造代码块执行
而构造代码块先于构造方法执行
但是这个题是有继承关系,先用的Student(int age,String name)这个构造方法然后调转到this(age)又到super(age)到父类的构造方法,这时是现执行父类中的构造代码块,然后父类的构造方法,然后这时才转到子类中,这时才是执行子类构造代码块和构造方法,这就和结果一样了
作者: 徐青松    时间: 2014-2-16 12:55
看着楼主的自问自答,首先必须明确的是:1、静态代码块优先于主方法执行,优先于构造代码块执行,不管有创建多少对象,静态代码块只执行一次。2、构造代码块一定会优先于构造函数先执行;3、最后才轮到普通代码块。你提的问题:因为子类执行了super(age);而先去执行父类中的构造方法((3)Persion100lishi),那么执行完后原本应该是执行子类的构造函数((4)Student100lishi)但是由于本类中遵循构造代码块要哦优先于构造函数执行,所以会优先执行子类Student的构造代码块({}Student);然后再执行Student子类的构造方法,就成了你现在的这样答案。




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