黑马程序员技术交流社区

标题: 初始化顺序问题 [打印本页]

作者: 杜佳瑞    时间: 2012-7-27 20:24
标题: 初始化顺序问题
本帖最后由 杜佳瑞 于 2012-7-27 21:50 编辑

网上看到的个小程序,觉得挺有意思的,可是不知道原理,大家给解释下
public class Test04  
{      
    //下面的这两行代码放置的顺序,跟执行结果是有关系的   
    private  String t1 = test();  
      
    {  
       System.out.println("初始化快!");  
    }  
    //上面的这两行代码放置的顺序,跟执行结果是有关系的   
      
    private String test(){  
        System.out.println("实例变量的执行过程");  
        return "test";  
    }  
  
    public Test04()  
    {  
        System.out.println("构造方法!");  
    }  
  
    public static void main(String[] args)  
    {  
        Test04 t2 = new Test04();  
    }  
      
}  
有些人误会了,我知道结果,目的是让大家说出为什么?
作者: fiend    时间: 2012-7-27 20:29
本帖最后由 fiend 于 2012-7-27 20:34 编辑

{  
       System.out.println("初始化快!");  
}  
这是构造代码块,比构造方法还早执行。所以你懂的啦。
测试了一下,我也不懂了。。。。。
作者: 杜佳瑞    时间: 2012-7-27 20:33
fiend 发表于 2012-7-27 20:29
{  
       System.out.println("初始化快!");  
}  

大哥看懂再说
作者: fiend    时间: 2012-7-27 20:35
杜佳瑞 发表于 2012-7-27 20:33
大哥看懂再说

。。。。。能别这么快吗?这不才刚改完答案。。。。。。。。。。。。
作者: 柳雷    时间: 2012-7-27 20:42
本帖最后由 柳雷 于 2012-7-27 20:45 编辑

不是你写在{}内的内容Java才把它当成初始化块,所以

//下面的这两行代码放置的顺序,跟执行结果是有关系的   
    private  String t1 = test();  
      
    {  
       System.out.println("初始化快!");  
    }  
    //上面的这两行代码放置的顺序,跟执行结果是有关系的  
执行结果:


//下面的这两行代码放置的顺序,跟执行结果是有关系的            
    {  
       System.out.println("初始化快!");  
    }
    private  String t1 = test();   
    //上面的这两行代码放置的顺序,跟执行结果是有关系的   
执行结果:

总结:初始化块的功能是完成类关于属性的设置任务的,并不一定非得写到{}内。另外初始化块实在类的构造方法之前执行的。

作者: 李菁    时间: 2012-7-27 21:05
先执行初始化块,再执行构造函数,如果有静态变量的最先执行静态变量变量
private  String t1 = test();   
    {  
       System.out.println("初始化快!");  
    }  
如果是这个顺序,输出结果是:实例变量的执行过程!初始化快!构造方法!
{  
     System.out.println("初始化快!");  
}  
private  String t1 = test();   
如果是这个顺序,输出结果为:初始化快!实例变量的执行过程!构造方法!


作者: 吴立杰    时间: 2012-7-27 21:27
老毕课程里提到的顺序如下,而我经过多次验证得出结论,显示初始化和构造代码块的先后顺序是根据它代码的顺序决定的。
Student s = new Student(); 在内存中的过程
        ① 将Student.class文件加载进内存。
        ②        如果p定义在方法中,那么栈内存会开辟一个p空间
        ③        在堆内存中给对象分配空间
        ④        给对象进行默认初始化值
        ⑤        给对象进行显示初始化
        ⑥        调用构造代码块给对象进行初始化5和6这两步是可以颠倒的!嘿嘿
        ⑦        调用构造函数给对象进行初始化,对象的初始化完毕
        ⑧        将堆内存中对象的首地址值赋给栈内存中的p变量
作者: 王程    时间: 2012-7-27 22:17
private  String t1 = test();   属于成员变量的初始化,
{  
       System.out.println("初始化快!");  //属于构造代码块,给对象进行初始化,对象一建立就运行,且优先于构造函数运行
    }  
public Test04()  //构造函数
    {  
        System.out.println("构造方法!");  
    }  

成员变量初始化是随着类的加载而存在的,而构造代码块与构造函数的初始化是建立对象后才有的,前者先存在,且存储在不同区域。

作者: 黑马王冬冬    时间: 2012-7-27 23:58
1.当系统开始执行构造器的执行体时之前,系统会先为该对象分配内存空间,并为这个对象的field执行默认初始化,此时对象已经产生,只是该对象还无法为外界访问,只能在该构造器内部通过this来引用。
2.普通初始化块,声明实例field指定的默认值都可以认为是对象的初始化代码,他们的执行顺序与源程序中的排列顺序相同。
3.程序输出为
实例变量的执行过程
初始化快!
构造方法!
  1. public class Test04  
  2. {      
  3.     private  String t1 = test();                  //1.t1为实例变量,在创建对象过程中会首先对实例field进行默认初始化,
  4.                                                       // 这时会执行test方法获取返回值,因而程序会首先打印字符串"实例变量的执行过程"
  5.     {                                                                                 
  6.        System.out.println("初始化快!");          //2.默认初始化按照初始化代码在程序中的排列顺序进行,因而接着打印字符串"初始化块"
  7.     }  
  8.       
  9.     private String test(){                                  //实例方法
  10.         System.out.println("实例变量的执行过程");  
  11.         return "test";  
  12.     }  
  13.   
  14.     public Test04()                                          //3.最后执行构造器执行体,打印字符串"构造方法!"
  15.     {  
  16.         System.out.println("构造方法!");  
  17.     }  
  18.   
  19.     public static void main(String[] args)  
  20.     {  
  21.         Test04 t2 = new Test04();                          //创建对象t2
  22.     }  
  23.       
  24. }  
复制代码





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