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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

对于类静态变量,静态初始化块的加载顺序是否和编写顺序有关,我和杨同学有分歧。
现在我自己写了一个例子,大家来看看:
  1. package com.heima;

  2. public class StaticInitTest {
  3. //定义静态变量(类变量)count,这个不是比较对象,下面的name是
  4. static int count = 2;

  5. //定义静态变量
  6. static String name = "我的黑马之路";
  7. //通过静态初始化块为name变量初始化
  8. static {
  9. System.out.println("StaticInitTest的静态初始化块!");
  10. name = "黑马编程";
  11. }

  12. public static void main(String[] args) {
  13. System.out.println("count的值:"+StaticInitTest.count);
  14. System.out.println("name的值:"+StaticInitTest.name);
  15. }
  16. }
复制代码
输出结果:

我改变程序中
//定义静态变量
static String name = "我的黑马之路";
//通过静态初始化块为name变量初始化
static {
System.out.println("StaticInitTest的静态初始化块!");
name = "黑马编程";
}
这两个static修饰的顺序,再看!!!结果:

在此表示杨同学,不知你怎么看?哈哈哈,哥有图有真相。。。。{:soso_e128:}

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

18 个回复

倒序浏览
求顶起。。。。。
回复 使用道具 举报
这个必须顶了,你的注释大法已经大成。
回复 使用道具 举报
自然顺序~~貌似真心没研究过·
回复 使用道具 举报
本帖最后由 王明(1988) 于 2012-4-25 20:27 编辑
李南江 发表于 2012-4-25 17:30
自然顺序~~貌似真心没研究过·
自然顺序~~貌似真心没研究过·

你看下,代码和输出结果,同意我的观点吗?
回复 使用道具 举报
补充总结以下:
静态变量、静态代码块之间
变量、构造代码块之间
取决与它们在类中出现的先后顺序
回复 使用道具 举报
王勃 中级黑马 2012-4-25 17:50:34
7#
Yes,我也是这么认为的,杨同学到现在还不认输。。。。
快来发帖,打擂台了哦,
回复 使用道具 举报
攻城狮 黑马帝 2012-4-25 17:51:02
8#
王明(1988) 发表于 2012-4-25 17:36
你看下,代码和输出结果,同意我的观点吗?
我的目的是让杨同学,认输。哈哈哈哈哈 ...

从实践证明应该没错·
回复 使用道具 举报
本帖最后由 真真姐 于 2012-10-21 14:49 编辑

看这个链接笔者的回复,里面总结了各方面的情况:http://bbs.itheima.com/forum.php?mod=viewthread&tid=12897  
这个问题其实远没有看上去的简单,说对也不对,以下的解答是之前的回复,也有片面的地方,具体答案请点击连接

实际这个问题很具有迷惑性,基本上看的同学们大眼一扫,你会感觉,就是啊,这不明摆着,值在那的啊,这正是楼上同学思考的方向比较偏,让一般人一时反应不过来
  1. 编译正常的话,就会加载了所有的静态值,而且只加载一次!
  2. main方法中没有操作任何代码,其实是在不断的打印name这个静态对象的值,
复制代码
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面交换顺序,分析谁在前,谁在后的执行结果
                 static
                        { // 静态函数,第一个加载
                                System.out.println("a静态块");
                                s = "我被编译了";                         // 这里为什么不报错 //编译的时候就把所有的静态属性全部加载!

                                System.out.println(s);                  //  这里你能获取到s吗? 系统会提示你,s还没有创创建,因为这里是第6行,你的对象在第8行才创建,编译不通过;                                                           
                        }
                static String s = "你只是在打印我";             //这里才创建的String对象,按编译顺序s是多少?是不是变成了 "你只是在打印我"
  1. 最终main函数中只是打印了s ,打印就是"你只是在打印我"
复制代码
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
换位置:static String s = "你只是在打印我" ;           //s是多少?是不是"你只是在打印我"
                                          
            static
                        {
                                s = "我被编译了" ;                        
                                System.out.println(s);              //Eclipse从上到下依次编译,编译到这,这里s是谁 ?是不是"我被编译了"
                        }
  1. 然后到这你又把这个s直接打印了出来,打印结果肯定会变成,"我被编译了" !!
复制代码
问题:有值不代表执行过了!  所以要明白,静态的变量的值加载,和静态变量代码的执行,是分开的!
总结:因为你的main方法中都是打印语句,你只是在-----打印编译后加载的值-----而已;
          对于实体代码的执行,只有一个地方执行了代码,就是静态块中的代码!详情看蓝色连接中的总结
  1. 给你说一个最简单的测试办法,不要用原始办法了
  2. static String S= "";{
  3.                      System.out.println("这个问题很费时间");         // 这才是测试代码是否执行的正确方法
  4.                }
  5. public static void main(String[] args){
  6. System.out.println("main" + " " + s);                                //main方法中都是打印的话,你只是在   {{{  打印编译后加载的值  }}}  而已;                              
  7. new Tsst();                                                          // 创建对象是检察各个代码执行顺序的途径
  8. }
复制代码
看这个链接笔者的回复,里面总结了各方面的情况:http://bbs.itheima.com/forum.php?mod=viewthread&tid=12897





回复 使用道具 举报
杨国祯 发表于 2012-4-25 17:55
这个问题之前已经解决了!看这个链接吧,我的回复很正确!http://bbs.itheima.com/forum.php?mod=viewthrea ...

System.out.println("count的值:"+StaticInitTest.count);
这一句没用,我忘记注释了。关键是交换之后,name被覆盖的结果。。
我觉得我没错啊。。。
回复 使用道具 举报
我又改写了程序:
  1. package com.heima;

  2. public class StaticInitTest {

  3. //通过静态初始化块为name变量初始化
  4. static {
  5. System.out.println("进入StaticInitTest的静态初始化块!");
  6. name = "黑马编程";
  7. System.out.println("要离开StaticInitTest的静态初始化块!");
  8. //System.out.println("静态初始化块中的name-----------"+name);
  9. }
  10. static String name= "我的黑马之路";
  11. {System.out.println("童鞋不明白我也没法了,自己好好看看吧"+name);}

  12. public static void main(String[] args) {
  13. //System.out.println("name的值:"+StaticInitTest.name);
  14. }
  15. }
复制代码
这次main里面没有执行语句我注释了。不存在执行,现在只讨论编译。
我用myeclipse的debug查看Expression你看一下:

下一张:

下一张:

下一张:

现在我将语句交换顺序,在debug,查看Expression,他们的加载是和上面的相反了。。
看图和代码:
  1. package com.heima;

  2. public class StaticInitTest {

  3. static String name= "我的黑马之路";
  4. {System.out.println("童鞋不明白我也没法了,自己好好看看吧"+name);}
  5. //通过静态初始化块为name变量初始化
  6. static {
  7. System.out.println("进入StaticInitTest的静态初始化块!");
  8. name = "黑马编程";
  9. System.out.println("要离开StaticInitTest的静态初始化块!");
  10. //System.out.println("静态初始化块中的name-----------"+name);
  11. }

  12. public static void main(String[] args) {
  13. //System.out.println("name的值:"+StaticInitTest.name);
  14. }
  15. }
复制代码
交换了静态变量和静态块的顺序。。。
debug的结果顺序图,都是step over(F6)。。。。

下一张:

最后一张:

杨,不知我这次错了吗?看看吧。。。。
回复 使用道具 举报
真心,搞不明白。。。。。俺觉得自己分析的没错啊。。。
回复 使用道具 举报
杨国祯 发表于 2012-4-25 17:55
强调:执行先后顺序的这个是改变不了的,官方的规定,你是改变不了的!那么代码什么时候执行呢-------》创 ...

真心,搞不明白。。。。。俺觉得自己分析的没错啊。。。
回复 使用道具 举报
王明(1988) 发表于 2012-4-25 18:02
System.out.println("count的值:"+StaticInitTest.count);
这一句没用,我忘记注释了。关键是交换之后, ...

看来你的观点还是有点问题,貌似杨同学说的很ok!
回复 使用道具 举报
本帖最后由 真真姐 于 2012-10-21 14:49 编辑

想要正确权威的回答,请看这个连接中笔者的回答:http://bbs.itheima.com/forum.php?mod=viewthread&tid=12897
---------------------------------------------------------------------------------------------------------------------------------------------
王明同学,还是没有好好的看我给你的分析啊! 费了几个小时给你打上去的,你就没好好想想!

你打印不打印,name的值都在那里!

难道你有打印语句name就有值,你不写打印语句name就没值?


最后总结:
name的值到底是谁:有多个静态为name赋值,就一直改变,谁是最后一个给name赋值, name就是谁,!
花了几个小时什么没干,就为了让你明白点又修改了很多回!你不去好好理解是不行的!

点评

好吧,我表示劳烦杨兄弟了。给你几块钱买夜宵吧。。。。  发表于 2012-4-25 21:09

评分

参与人数 1黑马币 +6 收起 理由
王勃 + 6 赞一个! 多谢杨兄弟的帮助,我再仔细分析分.

查看全部评分

回复 使用道具 举报
杨国祯 发表于 2012-4-25 21:01
还是没有好好的看我给你的分析啊! 费了几个小时给你打上去的,你就没好好想想!

你打印不打印,name的值 ...
不懂别再问我了兄弟 ,我花了几个小时什么没干,就为了让你明白点又修改了很多回!你不去好好理解是不行的!

童鞋们,要向杨同志学习,为人民解决问题不辞辛劳。
赞叹你一句:有容德乃大,无求品自高。
表示向杨兄弟看齐。:lol
回复 使用道具 举报
闹心啊 下午回了你两个帖子,一分没人给,,,,, 你得了最少四分了吧!!!
回复 使用道具 举报
杨国祯 发表于 2012-4-25 21:25
闹心啊 下午回了你两个帖子,一分没人给,,,,, 你得了最少四分了吧!!!

哈哈哈,哥笑死了,今天从16分涨到23分。。。。。耽误你赚分了吧,
还是哥狡猾。。。。可惜我不是版主,要不然定会给你加个3、4分。
可惜不是我,陪你到最后。。。。。
回复 使用道具 举报
杨国祯 发表于 2012-4-25 21:25
闹心啊 下午回了你两个帖子,一分没人给,,,,, 你得了最少四分了吧!!!

我的在线时间,奈何还是0小时,郁闷死了。。。。。
听人说设置刷新时间间隔就ok,可是我的还是不行,我估计是见鬼了今天,净范2了,程序搞错好几回。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马