黑马程序员技术交流社区

标题: 老毕06-07对象的初始化过程,迷糊,且属性显式初始化是? [打印本页]

作者: 寇龙飞    时间: 2012-7-20 10:52
标题: 老毕06-07对象的初始化过程,迷糊,且属性显式初始化是?
本帖最后由 寇龙飞 于 2012-7-28 13:45 编辑

Person p = new Person("zhangsan",20);

该句话都做了什么事情?
1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。
2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性。并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址付给栈内存中的p变量。

作者: 焦晨光    时间: 2012-7-20 11:40
1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。
   
    很明显 new用到了Person类,当然会先把该类加载到内存,并新创建一个该类对象;

2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
   
    java类首次装入时,会对静态成员变量或方法进行一次初始化;

3,在堆内存中开辟空间,分配内存地址。

    new创建对象时,在堆内存中开辟空间,给该对象分配内存地址;

4,在堆内存中建立对象的特有属性。并进行默认初始化。

    在堆内存中建立(copy)对象的特有属性 假设有(string name,int age)然后进行初始化;就是在定义Person类时,是否对对象的属性进行赋值,没有则是默认值;完整的将Person类和其属性 在对内存中 又copy一个出来;

5,对属性进行显示初始化。
   
    new Person("zhangsan",20);显式初始化就是将新创建的类所带的属性参数传入原先定义的类Person中,然后进行赋值:name=“zhangsan”;age=20 然后生成一个新类 Person 属性已被初始化。
    至此 一个 全新的类 Person 就出现在对内存中 且已经被显式初始化;

6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。

    如果定义的类中有构造代码块和构造函数的话,进行6、7步的操作;

8,将内存地址付给栈内存中的p变量。
   
    Person p = new Person("zhangsan",20);
    然后将刚才新创建的类Person在对内存中的地址付给p变量;



作者: 王超    时间: 2012-7-20 14:48
楼上讲的很明白
作者: 寇龙飞    时间: 2012-7-20 14:50
第一种形式:
  1. //文件名:ClassDemo.java

  2. class ClassDemo
  3. {
  4.         static
  5.         {
  6.                 System.out.println("2.类静态代码块初始化");
  7.         }
  8.                                                 //4.类非静态属性默认初始化  num = 0;
  9.         private int num = 100;//5.类非静态属性显式初始化

  10.         {
  11.                 System.out.println("6.构造代码块初始化,此时,mum="+ num);
  12.                 //num = 100:打印结果说明,构造代码块初始化晚于类非静态属性显式初始化
  13.         }
  14.        
  15.         ClassDemo()
  16.         {
  17.                 System.out.println("7.构造函数初始化");
  18.         }
  19. }

  20. class ClassTest
  21. {
  22.         public static void main(String[] args)
  23.         {
  24.                                                                 //mew时需要:1.内存中,加载ClassDemo.class文件
  25.                 ClassDemo classTest = new ClassDemo();//new的结果:3.堆内存中,开辟内存地址string
  26.                                                         //=赋值时:8.栈内存中,classTest获得内存地址string
  27.         }

  28. }
复制代码
编译、运行之
  1. D:\Java\Demo\06>javac ClassDemo.java

  2. D:\Java\Demo\06>java ClassTest
  3. 2.类静态代码块初始化
  4. 6.构造代码块初始化,此时,mum=100
  5. 7.构造函数初始化
复制代码
第二种形式:
  1. //文件名:ClassDemo1.java

  2. class ClassDemo
  3. {
  4.         static
  5.         {
  6.                 System.out.println("2.类静态代码块初始化");
  7.         }

  8.         {
  9.                 System.out.println("4.构造代码块初始化");
  10.                 //System.out.println("此时,num=“+ num);
  11.                 //上一行代码,如果不注释掉,编译报错”非法前向引用:
  12.                 //说明,类非静态属性默认(、显式)初始化晚于构造代码块初始化
  13.         }
  14.                                                         //5.类非静态属性默认初始化  num = 0;
  15.         private int num = 100;//6.类非静态属性显式初始化
  16.        
  17.         ClassDemo()
  18.         {
  19.                 System.out.println("7.构造函数初始化,此时,num="+ num);
  20.         }
  21. }

  22. class ClassTest
  23. {
  24.         public static void main(String[] args)
  25.         {
  26.                                                                 //mew时需要:1.内存中,加载ClassDemo.class文件
  27.                 ClassDemo classTest = new ClassDemo();//new的结果:3.堆内存中,开辟内存地址string
  28.                                                         //=赋值时:8.栈内存中,classTest获得内存地址string
  29.         }
  30. }
复制代码
编译、运行之
  1. D:\Java\Demo\06>javac ClassDemo1.java

  2. D:\Java\Demo\06>java ClassTest
  3. 2.类静态代码块初始化
  4. 4.构造代码块初始化
  5. 7.构造函数初始化,此时,num=100
复制代码
看来,其中,对象的非静态属性初始化(默认、显式)与构造代码块初始化顺序,与其在代码中的先后顺序有关。

在解决这个问题的过程中,碰到栈内存、堆内存、方法区等还不明白,mark下,先去吃饭换换脑,回来再看楼上二位朋友。




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