一:我们知道static是在类加载的时候就加载的,我们今天主要来讲一个static赋初值与不赋初值的问题。
也就是:
private static int sum;//(1)
private static int sum= 0; //(2)
我们知道在java中如果没有给整形变量赋初值,他的默认值为0。当我们在前面给sum已经赋值的情况下,比如我们给sum赋值为10,即 sum = 10,然后我们在执行上面的(1)语句,我们再来看看我们sum的值,我们发现sum的值任然为10,没有被(1)中的语句赋值为0,因为在前面sum已经包含了正确的缓存值,也就是被赋予了10。我们执行上面(2)中的代码,我们再来看sum的值,我们发现,sum被赋值为0了,这是因为我们在(2)中显示的定义了sum的值为0,所以他会被重新赋值为0。我们来看看下面代码的例子就知道了。
package test52;
public class cache {
static {
inittest();
}
private static int sum =0; //(1) 当将sum的值设置为0的时候,其运行后的结果就为4950,
/*
* 因为static是在程序加载前最先执行的,在开始执行完static代码块,执行inittest()方法,其中需要用到sum以及init,
* 因为开始程序还没有运行到初始化的值,所以采用默认的值,sum为0,init为false,执行完inittest()后sum的值为4950
* 然后 执行static sum =0;将sum再次设置为0,然后在初始化init将init再次设置false,
* 最后在调用getsum()的时候就会再次的调用inittest(),再次计算得到sum的值为4950
*/
// private static int sum ; (2) // 用这句将得到的结果为9900
/*
* 还是和上面的一样,首先是执行static代码,执行完static代码块的过程个上面的一样,执行完后的结果为4950,
* 但是下面他不会执行sum ,因为sum没有赋值,所以它会保留原来的sum值,也就是sum=4950.这也就是结果有差异的地方。*****
* 下面就是要执行init,因为它有赋值语句,所以这就是和上面的sum不执行的区别,因此赋值语句将init再次的sum 赋值为false,
* 最后在调用getsum()的时候再次的执行了inittest(),这时开始的sum为4950,所以执行完后的结果为9900.
* 这就是需要注意的地方,
*/
public static int getsum()
{
inittest();
return sum;
}
/*
* 如果采用的是private static int sum ,得到的是9900,问题最大就是在下面的这句初始化语句,如果将其写在方法前面就不会有这样的问题出现,
*/
private static boolean init = false;
public static synchronized void inittest()
{
if(!init)
{
for(int i=0;i<100;i++)
sum +=i;
init = true;
}
}
public static void main(String[] args) {
System.out.println(getsum());
}
}
执行(1)语句我们得到的4950,执行(2)中的代码我们得到的是9900。所以我们在以后使用static的时候一定要注意。
这个问题在java解惑中的52题,有详细的解析。又不好不对的地方,请大家指出来,谢谢。