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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 余银桂 中级黑马   /  2012-6-20 14:54  /  2194 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 余银桂 于 2012-6-20 17:00 编辑
  1. class A{
  2.         private  Integer x = 1;
  3.         
  4.         public A()
  5.         {
  6.         System.out.println(getX());
  7.         }
  8.         
  9.         public Integer getX()
  10.         {
  11.         return x;
  12.         }
  13. }
  14.         class B extends A{
  15.         private Integer x = 2;
  16.         public Integer getX()
  17.         {
  18.         return x;
  19.         }
  20.         public static void main(String[] args) {
  21.         new B();
  22.         }
  23. }


  24. //马虎了...  运行结果是null...
复制代码

12 个回复

倒序浏览
应该运行java B 是不是cmd里你输错了?
回复 使用道具 举报
原来解决过这个问题,请看注释
你的稍微有点不一样但是思路是一致的,都是初始化时父类构造函数调用子类的成员方法导致的结果..
  1. class A {
  2.         private Integer x = 1;//步骤4 然后再初始化父类的成员变量
  3.         public A()//步骤3 开始执行父类的构造函数,先开始构造父类
  4.         {
  5.                 System.out.println(getX()); //步骤5 问题出在这里 父类的构造函数中调用子类的方法,转而执行子类的方法.
  6.         }
  7.         public Integer getX()
  8.         {
  9.                 return x;
  10.         }

  11. }
  12. class B extends A {
  13.         private Integer x = 2;
  14.         public Integer getX()  //这个跟父类同名啊,
  15.         {
  16.                 return x;
  17.         }
  18.         public static void main(String[] args) {
  19.                 new B();//步骤1 开始new对象
  20.                 //步骤2 执行子类的构造函数 ,这里隐含了子类的构造函数
  21.                 //同时子类构造函数隐含了父类的构造函数,所以转而执行父类构造函数
  22.         }
  23.        

  24. }
复制代码
回复 使用道具 举报
为什么我复制了你的程序 却是可以运算出结果的,结果是null.
回复 使用道具 举报
车风波 发表于 2012-6-20 15:04
应该运行java B 是不是cmd里你输错了?

文件保存错了... 不过对于结果还是有点不懂 ,继承调用父类的,结果为什么是null...
回复 使用道具 举报
我编译运行都没有问题不过打印结果为 null;
我感觉这类问题每天都有人问一遍:
因为在创建子类的对象的时候;会先到子类构造构造函数初始化(没有定义构造函数为默认的空参构造函数B(){super()//隐式的}//隐式的);而在执行子类构造函数下面的代码之前会先执行父类的构造函数(super()//先执行这句话);而父类的构造函数A(){System.out.println(getX())}而这时的getX()方法不存在;因为父类对象没有建立嘛;而子类里而的getX();和x 还没有出现;因为现在子类的构造函数还没有执行完嘛;所以JVM会认为 getX()是一个没有指向的引用变量;而引用变量的默认初始化值为null;所以最后 的结果就是打印null;

评分

参与人数 1黑马币 +10 收起 理由
黄奕豪 + 10 第二句正解,不解析~~

查看全部评分

回复 使用道具 举报
余银桂 发表于 2012-6-20 15:13
文件保存错了... 不过对于结果还是有点不懂 ,继承调用父类的,结果为什么是null... ...

因为调用子类的getX()之前父类的构造函数还没有执行完,子类的构造函数肯定就没有执行,那么子类的成员变量还没有显式初始化(构造函数执行完了成员变量才会显式初始化),只有默认初始化,就是null。
回复 使用道具 举报
dev 中级黑马 2012-6-20 15:21:48
8#
程序本身没有错,可能是你运行时类名写错了。如果你运行A类的话就会报:
“Exception in thread "main" java.lang.NoSuchMethodError: main”这个错误,
因为A类中并没有main方法,所以不能独立运行,应该运行B类。
建议:
1、在源程序不变的情况下,文件名保存为B.java
2、编译时用:javac B.java
3、运行时用:java B
这样应该就不会错了,你试试。
回复 使用道具 举报
这是构造器初始化出的问题,前几天刚好遇到过。首先,class B 改写了父类的getx ()方法,要注意的是当我们创建子类的对象时系统会自动去调用父类的构造器。父类的构造器调用了getx ()方法,而这个方法的实现是束定到子类上的。即,调用子类改写的方法,此时子类的显示初始化给没有执行。x 是引用类型的数据系统会默认初始化为null 。打印结果为null .
回复 使用道具 举报
李天甲 发表于 2012-6-20 15:07
原来解决过这个问题,请看注释
你的稍微有点不一样但是思路是一致的,都是初始化时父类构造函数调用子类的成 ...

哈哈,步骤5说明一切,受教了
回复 使用道具 举报
李天甲 发表于 2012-6-20 15:07
原来解决过这个问题,请看注释
你的稍微有点不一样但是思路是一致的,都是初始化时父类构造函数调用子类的成 ...

看明白了!
回复 使用道具 举报
余银桂 发表于 2012-6-20 15:31
看明白了!

呵呵,这个在第10期里面有个类似的,只不过不是integer类型的,不会输出null,反而报错呵呵.
回复 使用道具 举报
本帖最后由 陆强强 于 2012-6-20 15:54 编辑

Integer x 是一个对象所以打印的是空,如果换成int x,就是0了
为什么空就是初始化的问题了。
先走子类构造函数,没有自定义就走默认的空参数构造函数,然后调用SUPER(),
走父类构造函数,这时候子类显示初始化Integer x = 2还没有完成,所以是空
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马