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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何旭栋 中级黑马   /  2012-7-25 15:01  /  2099 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何旭栋 于 2012-7-25 23:29 编辑
  1. class demo extends B{
  2.         private A m = new A();
  3.         private B b = new B();
  4.         private C c = new C();
  5.         public test2() {
  6.                 System.out.println("new demo");
  7.         }
  8.         public static void main(String[] args) {
  9.                 new test2();
  10.         }
  11. }
  12. class A{
  13.          public A() {
  14.                  System.out.println("new A");
  15.          }
  16. }
  17. class B extends A{
  18.         public B() {
  19.                 System.out.println("new B");
  20.         }
  21. }
  22. class C{
  23.         public C() {
  24.                 System.out.println("new C");
  25.         }
  26. }
复制代码
结果:
new A
new B
new A
new A
new B
new C
test2
对结果不解,原以为结果是A->A->B->C->A->B->demo或者A->B->demo->A->A->B->C,哪位大虾能解释下,最好能内存情况也一起说说

8 个回复

倒序浏览
本帖最后由 肖琦 于 2012-7-25 20:36 编辑

图中,黑色数字是代码运行的流程,红色字体是描述的,蓝色字体是输出部分顺序

图片画的不是很好,但我相信你能看懂
希望对你有帮助............

QQ截图20120725150929.png (69.31 KB, 下载次数: 35)

QQ截图20120725150929.png

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 马州州 于 2012-7-25 20:28 编辑

我画图画着画着画凌乱了。。。
线太多了,没法整了
我直接说好了
首先代码有问题,不知道你怎么能运行出来结果。。。
就是那个test2没有返回值,还对一个函数创建对象。。。囧一个
运行步骤是这样的
首先执行主函数,建立test2的对象
因为demo继承b,所以初始化B的对象
B继承A,所以初始化A,直接运行A的程序 打印new A
然后对B进行初始化,打印new B

这时开始执行private A m = new A();
打印new A
继续private B b = new B();
跟上面说的一样,打印
new A
newB
C没有继承关系直接打印
newC
下面最后调用Test2的构造函数
new demo


楼主不好意思啊,画图没画成,线太多了,我自己看着都晕

回复 使用道具 举报
class demo extends B{//6:对本类初始化
        private A m = new A();//7:初始化A对象对应的类
        private B b = new B();//9:初始化B对象对应的类
        private C c = new C();//14:初始化C对象对应的类
        public test2() {
                System.out.println("new demo");//16:执行test2构造函数,打印Demo
        }
        public static void main(String[] args) {
                new test2();//1:读main中的这句,初始化test2对象对应的类
        }
}
class A{//3:再上层父类初始化.  11:父类初始化
         public A() {//4:执行再上层父类构造函数,打印一个A  8:调用A构造函数,打印A   12:执行A构造函数,打印A
                 System.out.println("new A");
         }
}
class B extends A{//2:父类初始化  10:初始化B类
        public B() {//5:执行父类构造函数,打印一个B    13:执行B构造函数,打印B
                System.out.println("new B");
        }
}
class C{
        public C() {//15:执行C构造函数,打印C
                System.out.println("new C");
        }
}

评分

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

查看全部评分

回复 使用道具 举报
楼主,你程序挂了哎。。。。
程序有点问题
编译失败
回复 使用道具 举报
首先你的代码是有问题的啊。
类名demo没大写,函数test2没有返回值,而且new了一个函数。。。
  1. class Test2 extends B{
  2.         private A m = new A();
  3.         private B b = new B();
  4.         private C c = new C();
  5.         public Test2() {
  6.                 System.out.println("new demo");
  7.         }
  8.         public static void main(String[] args) {
  9.                 new Test2();
  10.         }
  11. }
  12. class A{
  13.          public A() {
  14.                  System.out.println("new A");
  15.          }
  16. }
  17. class B extends A{
  18.         public B() {
  19.                 System.out.println("new B");
  20.         }
  21. }
  22. class C{
  23.         public C() {
  24.                 System.out.println("new C");
  25.         }
  26. }
复制代码
简单的把处理过程说一遍:
1、读取主函数代码 new Test2(),建立类Test2的对象。
2、类Test2有继承关系,所以先要初始化Test2的父类B的对象。
3、类B有继承关系,所以要先初始化B的父类A的对象。
4、类A没有继承关系,也没有成员,所以直接运行构造函数。
     打印“new A”
5、类A初始化完成之后,其new出来的对象从内存中消失。
     对类B进行初始化,运行B的构造函数。
     打印“new B”
6、类B初始化完成之后,其new出来的对象从内存中消失。
     对类Test2进行初始化。
注意:Test2有成员,所以要先在内存空间中分配成员变量。
7、第一个读取的成员变量是A。
     类A没有继承关系,也没有成员,所以直接运行构造函数。
     打印“new A”
8、第二个读取的成员变量是B。
     类B有继承关系,所以要先初始化B的父类A的对象。
     类A没有继承关系,也没有成员,所以直接运行构造函数。
     打印“new A”
     类A初始化完成之后,其new出来的对象从内存中消失。
     对类B进行初始化,运行B的构造函数。
     打印“new B”
9、第三个读取的成员变量是C
     类A没有继承关系,也没有成员,所以直接运行构造函数。
     打印“new C”
10、当Test2的成员变量都初始化完成之后,调用Test2的构造函数。
     打印“new Demo”

评分

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

查看全部评分

回复 使用道具 举报
楼主首先要明确的是:当java虚拟机初始化一个类的时,要求它的所有父类都已经被初始化,下面看一下程序的运行流程:主函数中调用test2()方法,test2()方法是定义在demo中的方法,需要加载demo类型,demo类的直接父类是B类,B类的直接父类是A,所有要创建一个Test2类型的对象,首先要创建A类对象,调用A类的构造方法,打印new A,然后有了A后,接下来创建B类型对象,调用B类的构造方法,打印new B,然后创建demo类对象,demo类中有以下成员变量,A类型的a,创建a会调用A的构造方法,打印new A,接下来,B类型的b,B类的直接父类是A,需要先初始化A类,故先调用A类的构造方法,打印new A,有了A后,调用B类的构造方法,打印new B,还有一个C类型的成员变量,调用C的构造函数,直接打印new C,最后执行后最后执行test2()方法,打印 new demo。

你只要记住,如果一个类有父类的话,初始化这个类的时候要求它的直接父类已经初始化了,同样他的直接父类也是这样,被初始化之前看下自己的直接父类是不是已经被初始化了。
回复 使用道具 举报
楼主别总搞这样东西 没有用 这种东西搞的太乱了,不用这么复杂吧
回复 使用道具 举报
谢谢各位了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马