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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杜佳瑞 中级黑马   /  2012-7-27 20:24  /  2627 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杜佳瑞 于 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();  
    }  
      
}  
有些人误会了,我知道结果,目的是让大家说出为什么?

评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 赞一个!

查看全部评分

8 个回复

倒序浏览
本帖最后由 fiend 于 2012-7-27 20:34 编辑

{  
       System.out.println("初始化快!");  
}  
这是构造代码块,比构造方法还早执行。所以你懂的啦。
测试了一下,我也不懂了。。。。。
回复 使用道具 举报
fiend 发表于 2012-7-27 20:29
{  
       System.out.println("初始化快!");  
}  

大哥看懂再说
回复 使用道具 举报
杜佳瑞 发表于 2012-7-27 20:33
大哥看懂再说

。。。。。能别这么快吗?这不才刚改完答案。。。。。。。。。。。。
回复 使用道具 举报
本帖最后由 柳雷 于 2012-7-27 20:45 编辑

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

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


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

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

评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 赞一个!

查看全部评分

回复 使用道具 举报
先执行初始化块,再执行构造函数,如果有静态变量的最先执行静态变量变量
private  String t1 = test();   
    {  
       System.out.println("初始化快!");  
    }  
如果是这个顺序,输出结果是:实例变量的执行过程!初始化快!构造方法!
{  
     System.out.println("初始化快!");  
}  
private  String t1 = test();   
如果是这个顺序,输出结果为:初始化快!实例变量的执行过程!构造方法!

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

成员变量初始化是随着类的加载而存在的,而构造代码块与构造函数的初始化是建立对象后才有的,前者先存在,且存储在不同区域。
回复 使用道具 举报
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. }  
复制代码

评分

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

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马