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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© java陈辉 中级黑马   /  2014-1-10 23:04  /  1567 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

下面这段代码中i的结果为什么是2?求详细的解释。
class Super{
        int i=0;
        public Super(String a){
                System.out.println("A");
                i=1;       
        }
        public Super(){
                System.out.println("B");
                i+=2;
        }
}
class Demo extends Super{
        public Demo(String a){
                super();
                System.out.println("C");                               
        }
        public static void main(String[] args){
                int i=4;
                Super d=new Demo("A");
                System.out.println(d.i);
        }
}

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 神马都是浮云

查看全部评分

8 个回复

倒序浏览
class Demo extends Super{
         public Demo(String a){
                 super();  //这句话调用了父类super的构造函数super(),所以答案是2
                 System.out.println("C");                                
        }

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 赞一个!

查看全部评分

回复 使用道具 举报
注意:你需要弄清楚的就是,这里面的i的意义。这个程序里有两种i变量,一个是成员变量i,定义在类Super中,存在堆内存中,并随着对象的建立而进入内存中;一个是局部变量i,定义在了main主函数中,存在于栈内存中。下面说一下此程序的执行步骤:1.执行main中的语句,先是int i=4;此时在栈内存中为此i开辟一个空间,并赋值为4;2,执行语句  Super d=new Demo("A");此时会将父类中的成员变量i存入堆内存中,并赋值为0,但是会执行语句   
public Demo(String a)
      {
                super();
                System.out.println("C");                                
        }
则此时会再调用
  public Super()
      {
                System.out.println("B");
                i+=2;
        }
此时会输出B,并将i赋值为2,注意,此赋值的i是赋值的堆内存中的i,而不是局部变量i,然后再输出C,然后执行语句: System.out.println(d.i);此时是打印d.i,即打印对象的成员变量,即打印堆内存中的变量的值,所以结果为2.

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 很给力!

查看全部评分

回复 使用道具 举报
你输出的i是对象d的成员变量,是在栈内存中,使局部变量,所以和主函数中定义的int i=4没有关系,在调用函数 public Super(){
                System.out.println("B");
                i+=2;
        }
的时候i由0变成了2

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
先从主函数来看:
public static void main(String[] args){
                int i=4;
                Super d=new Demo("A");
                System.out.println(d.i);
        }
Super d=new Demo("A"); 这句话是使用一个父类的引用指向子类的对象。
new Demo("A"); 创建Demo的对象。调用Demo类的有参构造函数
public Demo(String a){
                super();
                System.out.println("C");                                
        }
执行构造函数,第一句话super()是调用父类Super的无参构造函数
   public Super(){
                System.out.println("B");
                i+=2;
        }
先执行  System.out.println("B");打印输出B
然后再执行 i+=2;
在Super类里面定义了i=0;所以i+=2的结果为2
调用完父类Super的无参构造函数之后再返回Demo类的有参构造函数执行 System.out.println("C");
最后返回主函数执行: System.out.println(d.i); 输出d.i的结果是2

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 很给力!

查看全部评分

回复 使用道具 举报
首先主函数new Demo后,会读到Demo的带参数的构造方法,因为编译看父类,运行看子类,然后读到super();会找到相应的父类中的构造函数,先执行父类构造函数中的代码,先打印一个“B”,这时i+=2执行,这句话意思和i=i+2是一样的,只是前者会有类型提升,后者没有,在Super类里面定义了i=0,所以i的值是2,然后回到Demo中执行,打印一个“C”。

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
super()调用的是父类无参的构造方法,i=i+2,初始i是0,因此i等于2

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
首先,d.i  d是Super的对象,肯定调用的是Super类中的属性,排除i=4。然后生成一个new Demo(0的对象
回复 使用道具 举报
首先,d.i  d是Super的对象,肯定调用的是Super类中的属性,排除i=4。然后生成一个new Demo("A")的对象,调用Demo的构造方法,由于其中写了super()方法,调用Demo父类无参的构造方法,i+=2,原来是0,所以i的值变成2,就是d.i的值
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马