黑马程序员技术交流社区

标题: static静态代码块 [打印本页]

作者: 严磊    时间: 2011-8-29 23:50
标题: static静态代码块
public class S {
        static int i = 5;
        static{
                System.out.println(i++); //如果这里不要++ ,输出的是5,5,6       
                      }
        static{
                System.out.println(i++);  //如果这里不要++ ,输出的是5,6,6
        }
        public static void main(String [] avgs){
                System.out.println(i++);   //这里的++似乎没有起作用,没有自加
}
输出的结果为 5, 6 ,7
他们依次是这样执行的、啊
作者: 匿名    时间: 2011-8-30 00:34
静态方法在类加载完成后,就开始执行。 所以 第一个i =5 然后 i++ =6   所以第二个 i=6  在 ++ 得到 所以第三个i 是7  。  i++ 的意思是 执行之后再加1 。
作者: 匿名    时间: 2011-8-30 01:02
当JVM加载S这个类的时候,会首先为静态变量赋值即将 i赋值为5,然后会执行第一个静态代码块,
然后执行 System.out.println(i++); 此时是先引用i的值5,所以输出5,然后i再加1,i就等于6,继续执行下一个
静态代码块原理一样也是先引用后自加,i的值就为7,最后执行main方法,同理是先应用后自加,最后i的值为8。
作者: 李叶    时间: 2011-8-30 02:32
要想弄明白这个问题,首先有两个知识点必须要弄清楚的

第一个知识点就是++i和i++的区别:
从形式上,我们就可以很清楚的看出,++i的两个+号在前面,而i++的两个+号在后面
所以,++i的含义是,先让这个变量的值+1,然后再使用这个变量
而i++的含义则是,先使用这个变量的值,然后再让这个变量的值+1
所以,就拿你问题中的例子吧,System.out.println(i++);这行语句的实际上执行的代码就是
System.out.println(i);
i=i+1;
这时如果把i++改成++i,就相当于把i=i+1放到System.out.println(i)的上面
同理,如果你把++去掉的话,就相当于把i=i+1这句话去掉了

第二个知识点就是static代码块的特点
说起static代码块,我可能要扯的稍微远一点~就是关于JAVA加载类的机制
首先,我们知道,JAVA是通过虚拟机来运行的
所以,当你运行一个类的时候,实际上就是虚拟机在运行这个类
但是,由于定义这个类的代码都是保存在文件中的,而文件是保存在你的硬盘上,而虚拟机是在内存中运行的
所以虚拟机要想运行这个类的话,它必须首先要从硬盘上把这个类的代码读取到内存中,这里的“读取”就可以称之为“加载”
于是,这个类中static代码块中的语句,就是在JAVA虚拟机加载这个类的时候被执行的~
当虚拟机加载完毕你这个类之后,才会开始运行这个类,也就是执行main方法里面的语句

所以,你的这段程序所运行的顺序是(其中的++我都已经拆成意义相同的代码):[code=java]//第一步:初始化静态变量和执行static代码块中的语句,顺序为自上而下执行
static int i = 5;   //初始化静态变量i

static{
   System.out.println(i);        
   i=i+1;  //如果上面没要++,则这行语句不存在
}

static{
  System.out.println(i);        
  i=i+1;   //如果上面没要++,则这行语句不存在
}

//第二步:执行类中的方法
public static void main(String [] avgs){
  System.out.println(i);
  i=i+1;   //这里可以很清楚的看出,由于i是在输出后才+1的,所以++就好像没起作用一样
} [/code]好了,说了这么多,总结一下吧:
1、++说白了就是一句i=i+1,只不过这个i=i+1是在你当前执行这行的语句之外执行的,不是之前就是之后,由++的位置决定
2、所谓的“JAVA虚拟机加载类”的过程,说白了,就是在你第一次使用这个类的时候,JAVA虚拟机把这个类的代码从硬盘上读取到内存中的过程。static代码块中的内容都是在这个时候被执行的,而且也只会在这个时候被执行

之所以要强调最后几个字的原因是,只有你第一次使用这个类的时候,虚拟机才会把它从硬盘中加载到内存中
之后的话,只要虚拟机不关闭,你以后再使用这个类的时候,虚拟机就可以直接在内存中使用它了
所以,“只会在这个时候被执行”的含义,还需要进一步的思考和理解噢~
[ 本帖最后由 李叶 于 2011-08-30  10:49 编辑 ]
作者: 匿名    时间: 2011-8-30 10:04
静态语句块是一定会执行
作者: 匿名    时间: 2011-8-30 12:03
了解i++的规则先。
作者: 匿名    时间: 2011-8-30 13:38
标题: 回复 板凳 的帖子
晓得了 ·搞复杂啦3Q
作者: 徐西宏    时间: 2011-8-30 16:14
类中的静态代码块,不存在于任何方法中,Java虚拟机加载类时会执行这些静态代码块,
楼主所写的代码,有多个静态代码块,所以Java虚拟机就会按照它们在类中出现的顺序依次执行,
而且静态代码块只会被执行一次。按照此描述估计楼主能看懂代码的意思
[ 本帖最后由 徐西宏 于 2011-08-30  16:16 编辑 ]
作者: 匿名    时间: 2011-8-30 17:53
按照楼主所写的代码,程序运行是按顺序运行的,所出现的三种结果的运行过程如下的:
第一个输出结果、第一条语句(i):输出5,没有任何运算;第二条语句(i++):先输出5,再运算i=5+1=>i=6;第三条(i++)输出6,再运算i=6+1=>i=7,因此输出结果就是5,5,6.
第二个输出结果、第一条语句(i++):输出5;运算i=5+1=>i=6;第二条语句(i):输出6,不做运算;第三条语句(i++):输出6,再运算i=6+1=>i=7,因此输出结果就是5.6.6.
第三个输出结果、第一条语句(i++):输出5,再运算i=5+1=>i=6;第三条(i++)输出6,再运算i=6+1=>i=7;第三条语句第三条(i++)输出7,再运算i=8+1=>i=8,因此输出结果就是5,6,7
楼主了解好i++,++i的运算规则还有静态代码的运算顺序,疑问就很好解决。




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