A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© quick3g 中级黑马   /  2014-12-24 01:37  /  1334 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

子类中成员变量与构造函数的加载顺序问题,不明白,哪位大神知道?
  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. }
复制代码

9 个回复

倒序浏览
在不涉及继承的时候,成员变量初始化是在构造函数之前的。
你这里涉及到了继承,当对子类建立对象的时候,会先看父类的静态初始化,对类进行初始化,然后是子类的静态初始化,这是就加载了staticNum,然后是父类的构造方法,但是这里用的方法print()又被子类复写了,会使用子类的方法,可是这时的num,str,arr还是默认初始化,所以是num=0,str=null,arr=null,才会出现你说的问题。我是这样理解的,不对请指正
回复 使用道具 举报
路过看看。
回复 使用道具 举报
一楼说的是正确的,确实还没有给成员变量进行初始化,就直接在调用了B类的函数了
回复 使用道具 举报
String和Array都开辟了空间,有一个默认值,但是还没有初始化值。
而数组的长度也没有加载,只是定义了一个空间,所以会报错。
初始化值需要在构造函数执行后才会把值赋给参数。

这些是我的理解。
回复 使用道具 举报
这个问题让我也学习了。谢谢分享。
回复 使用道具 举报
父类空参构造函数执行print()的时候子类中的成员变量都还没有初始化所以默认的是0和null
回复 使用道具 举报
月老~牵红线 发表于 2014-12-24 09:20
在不涉及继承的时候,成员变量初始化是在构造函数之前的。
你这里涉及到了继承,当对子类建立对象的时候, ...

这里说的是不是有点矛盾:你认为变量初始化在构造函数之前,那么应该是子类的变量初始化了,才会进入子类构造函数(先执行父类构造函数内容,再执行子类构造函数内容),这是就不会出现变量未被初始化的情况。所以,应该是构造函数先于成员变量的初始化,才会导致问题中的结果。
回复 使用道具 举报
lnscore 中级黑马 2014-12-24 23:07:00
9#
我赞同一楼的说法
回复 使用道具 举报
月老~牵红线 发表于 2014-12-24 09:20
在不涉及继承的时候,成员变量初始化是在构造函数之前的。
你这里涉及到了继承,当对子类建立对象的时候, ...

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