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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马李昂 中级黑马   /  2013-7-30 00:16  /  1549 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杜光 于 2013-7-30 10:20 编辑

class X
{
        Y y1 = new Y();
        X()
        {
                System.out.print("X");
        }
}
class Y
{
        Y()
        {
                System.out.print("Y");
        }
}
class Z extends X
{
        Y y =new Y();
        Z()
        {
                System.out.print("Z");
        }
}
class Demo
{
        public static void main(String[] args)
        {
                new Z();
        }
}

输出结果为 YXYZ ,请教大家Y为什么先于X出现,说一下内存,谢谢大家

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

11 个回复

倒序浏览
类Z继承类X,那么当创建Z类对象时,Z对象直接读取父类X的数据,即代码Y y1 = new Y();,参阅父类X的构造函数是否有初始化类X中的数据,没有初始化,则执行Y y1 = new Y();然后执行super(),也就是父类X的构造函数。所以先打印Y,在打印X。

与你一同学习。{:soso_e141:}

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

回复 使用道具 举报
new Z()创建Z的对象时 先执行了new Y()在内存中创建了Y的对象y 输出Y ;
后加载Z的构造函数Z(),Z()中第一行默认有super(),调用了父类X的构造方法 输出X 并对类X初始化
又创建了Y的对象y1 输出Y
最后输出Z


希望能帮到你  共同学习哈

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

回复 使用道具 举报
class X
{
        Y y1 = new Y();
        X()
        {
            System.out.print("X ");
        }
}
class Y
{
        Y()
        {
           System.out.print("Y ");
        }
                Y(int a)
        {
           System.out.print("Y...."+a);
        }
}
class Z extends X
{
        Y y =new Y(3);
        Z()
        {
                super();
                System.out.print(" Z ");
        }
}
class Demo
{
        public static void main(String[] args)
        {
            new Z();
        }
}

你的代码我稍微给你改 了一下,你可以看看,最后的结果是:Y X Y...3 Z  我相信这样你会看的更清楚些,因为你主函数是new 一个Z的对象,而Z是X的子类,所以就要先调用父类的构造函数,即Z中默认调用super()语句。

Y y=new Y();这一句话都做了什么事,

1,因为new用到了Y.class.所以会先找到Y.class文件并加载到内存中。
2,执行该类中的static代码块,如果有的话。给Y.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性。并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址付给栈内存中的y变量。
所以Y比X先打印,不知道这样讲你能不能明白。

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

回复 使用道具 举报
因为z类继承了x 类,当建立z类对象时。必然是其父类x先初始化。而初始化一个x类会先初始化其成员变量,所以会执行  Y y1 = new Y();接着建立x对象。x类初始化完成后。才会初始化z。这样又按顺序先初始化其成员变量,执行  Y y1 = new Y();接着调用自身的构造方法,执行System.out.print("Z");  这个例子就是验证了子类的初始化过程。要建立子对象。必先初始化你父类。也就是先要生成父类对象。先有父才有子嘛!在补充一些内容  当初始化父类时。如果子类构造方法中没有显示调用父类有参构造方法。会默认调用其无参构造方法。在子类中如果访问到的数据是静态数据。这时初始化要看是子类定义的还是父类定义的。如是子类定义的,此时也会初始化父类的静态部分。如是父类定义的。则此时不会初始化子类。因为虚拟机很智能。认为没必要。就不会加载了。

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

回复 使用道具 举报
子类的所有的构造函数默认都会访问父类中空参数的构造函数,
因为子类每一个构造函数内的第一行都有一句隐式的super();
当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
建议多看看毕向东老师的教学视频,面向对象专栏里有详细的说明。

评分

参与人数 1技术分 +1 收起 理由
杜光 + 1 每天提问并回答问题,是对知识的复习和积累.

查看全部评分

回复 使用道具 举报
学习来了..
回复 使用道具 举报
王松松 发表于 2013-7-30 01:35
类Z继承类X,那么当创建Z类对象时,Z对象直接读取父类X的数据,即代码Y y1 = new Y();,参阅父类X的构造函 ...

恩 谢谢! 共同学习
回复 使用道具 举报
breaveheart 发表于 2013-7-30 09:35
子类的所有的构造函数默认都会访问父类中空参数的构造函数,
因为子类每一个构造函数内的第一行都有一句隐 ...

恩 谢谢 共同学习:)
回复 使用道具 举报
影响力147753321 发表于 2013-7-30 08:47
因为z类继承了x 类,当建立z类对象时。必然是其父类x先初始化。而初始化一个x类会先初始化其成员变量,所以 ...

恩 谢谢 ,共同加油!:)
回复 使用道具 举报
hoyouly 发表于 2013-7-30 07:19
class X
{
        Y y1 = new Y();

这个内存解释的最清楚,是我想知道的,谢谢,共同学习:)
回复 使用道具 举报
手心里的温柔 发表于 2013-7-30 01:47
new Z()创建Z的对象时 先执行了new Y()在内存中创建了Y的对象y 输出Y ;
后加载Z的构造函数Z(),Z()中第一 ...

恩  谢谢 共同进步:)
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马