黑马程序员技术交流社区

标题: 两中情况创建new Demo()对象的步骤问题? [打印本页]

作者: 高鑫    时间: 2012-5-5 19:17
标题: 两中情况创建new Demo()对象的步骤问题?
  1. class Demo
  2. {
  3.         static Demo d=new Demo();       //《1》
  4.         Demo()
  5.         {}
  6. }
  7. class Test
  8. {
  9.         public static void main(String[]args)
  10.         {
  11.                 Demo a=new Demo();        //《2》
  12.         }
  13. }
  14.        

  15. //-------------------------------程序二----------------------------------------
  16.        
  17. class Demo
  18. {
  19.         Demo d=new Demo();                        //《3》
  20.         Demo()
  21.         {
  22.         }
  23. }
  24. class Test
  25. { public static void main(String[] args)
  26.         {
  27.                 Demo a=new Demo();                //《4》
  28.         }
  29. }
复制代码
程序一中,运行class Test我认为是这样执行的:
1,读到《2》时,先把Demo类加载进内存
2,这时运行《1》,创建一个Demo类的对象
3,然后创建的对象的地址赋值给d,d存放在方法区,这时内存加载完成
4,程序又回到《2》,创建第二个Demo类的对象
5,把第二个Demo对象的地址赋值给a,a在栈内存中
请问以上步骤我理解的是否正确,是否有少了什么步骤?
程序二中,
1,运行到《4》时加载Demo类进内存
2,当运行到《3》时,创建Demo类的对象,因为d不是静态的,放在堆内存,所以这里貌似陷入了一种创建对象和加载类的循环,但我搞不明白这个循环的步骤是怎么样的。谁能详细告知。还有这个对象(《3》代码建立的对象)到底建立起来了没有??
为什么程序2编译可以通过呢?


作者: 倪杭乘    时间: 2012-5-5 20:01
第一张的图 红色的是步骤
第二个程序堆内存溺出了,不停的创建Demo对象
作者: 杨志    时间: 2012-5-5 20:01
关于在JAVA中对象的实例化步骤。
这个在11 行实例化的时候。会先给静态变量分配内存空间并初始化,即使静态变量写在最后
也会先被执行。然后执行静态代码块。
  1. static{
  2. System.out.println("test");
  3. }
复制代码
这句会在静态变量初始化完了之后去执行。
当然而你这里没有静态代码块。只有一个静态变量:
  1. static Demo d=new Demo();
复制代码
这句就会在最先执行。这时候d就会被存放在方法区。
然后再在内存中为Demo分配内存空间,并做默认初始化。也就是所有的变量都初始化为默认变量。
完了之后,再做显示赋值。然后执行非静态方法块。最后执行默认构造方法。如:
在你的11 行下面加一句:
  1. {
  2.         System.out.println("test....");
  3.       }
复制代码
那么它就会在你的构造函数先被执行。
然后再去执行所谓的构造方法。
当然你的第二个方法。可以编译过!但是运行会报错。
我想是因为编译器只是去严格的去检查语法。关于这个运行时的错误是不会检查到的。
就像你去写了个死循环。那么编译器是不会给你检查出来的。这些个都是运行时错误。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2