黑马程序员技术交流社区

标题: 子类成员变量与构造函数的加载顺序问题 [打印本页]

作者: quick3g    时间: 2014-12-24 01:37
标题: 子类成员变量与构造函数的加载顺序问题
子类中成员变量与构造函数的加载顺序问题,不明白,哪位大神知道?
  1. class ExtendsDemo2
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 new B();
  6.         }
  7. }
  8. class  A
  9. {
  10.         int num=-100;
  11.         A(){
  12.                 this.print();
  13.         }
  14.         void print(){
  15.                 System.out.println(num);
  16.                 System.out.println("...A...");
  17.         }
  18. }
  19. class  B extends A
  20. {
  21.         int num=99;
  22.         static int staticNum=111;
  23.         int[] arr={11,22,33};
  24.         String str="B类";
  25.         void print(){
  26.                 System.out.println(num);//怎么会=0呢,已经定义并初始化了呀!
  27.                 System.out.println(str);//怎么=null呢?
  28.                 System.out.println(staticNum);
  29.                 //System.out.println(arr[0]);//为何会报错???变量不是已经定义了么?
  30.                 System.out.println("...B..");
  31.         }
  32. }
复制代码

作者: 月老~牵红线    时间: 2014-12-24 09:20
在不涉及继承的时候,成员变量初始化是在构造函数之前的。
你这里涉及到了继承,当对子类建立对象的时候,会先看父类的静态初始化,对类进行初始化,然后是子类的静态初始化,这是就加载了staticNum,然后是父类的构造方法,但是这里用的方法print()又被子类复写了,会使用子类的方法,可是这时的num,str,arr还是默认初始化,所以是num=0,str=null,arr=null,才会出现你说的问题。我是这样理解的,不对请指正
作者: 芭芭拉2    时间: 2014-12-24 10:09
路过看看。
作者: xiao飞    时间: 2014-12-24 10:51
一楼说的是正确的,确实还没有给成员变量进行初始化,就直接在调用了B类的函数了
作者: zqbemail    时间: 2014-12-24 11:08
String和Array都开辟了空间,有一个默认值,但是还没有初始化值。
而数组的长度也没有加载,只是定义了一个空间,所以会报错。
初始化值需要在构造函数执行后才会把值赋给参数。

这些是我的理解。
作者: 双鱼座程序员    时间: 2014-12-24 13:25
这个问题让我也学习了。谢谢分享。
作者: 青衫禅客    时间: 2014-12-24 13:36
父类空参构造函数执行print()的时候子类中的成员变量都还没有初始化所以默认的是0和null
作者: yninggis    时间: 2014-12-24 22:37
月老~牵红线 发表于 2014-12-24 09:20
在不涉及继承的时候,成员变量初始化是在构造函数之前的。
你这里涉及到了继承,当对子类建立对象的时候, ...

这里说的是不是有点矛盾:你认为变量初始化在构造函数之前,那么应该是子类的变量初始化了,才会进入子类构造函数(先执行父类构造函数内容,再执行子类构造函数内容),这是就不会出现变量未被初始化的情况。所以,应该是构造函数先于成员变量的初始化,才会导致问题中的结果。

作者: lnscore    时间: 2014-12-24 23:07
我赞同一楼的说法
作者: quick3g    时间: 2014-12-25 01:06
月老~牵红线 发表于 2014-12-24 09:20
在不涉及继承的时候,成员变量初始化是在构造函数之前的。
你这里涉及到了继承,当对子类建立对象的时候, ...

但是构造方法的作用是于对类的成员变量进行初始化呀。出现这样的情况,说明变量已经存在,并且已经赋默认值,但是并没有赋给定的值。内部会不会是这样子:
int num=0;//首先声明变量,赋默认值。
//......其它变量.............
print();//执行print方法
num=99;//最后再赋值???
//如果是这样,不是浪费吗?num=0;可以,为何不一步到位直接初始化为99呢??




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