package com;

public class StaticVariableTest {

	private static StaticVariableTest svt = new StaticVariableTest();// 语句(1)
	private static int count1;// 语句(2)
	private static int count2 = 0;// 语句(3)

	private StaticVariableTest() {// 语句(4)
		count1++;
		count2++;
	}

	public static StaticVariableTest getInstance() {// 语句(5)
		return svt;
	}

	public static void main(String[] args) {
		StaticVariableTest svt = StaticVariableTest.getInstance();// 语句(6)
		System.out.println("count1:" + svt.getCount1());// 语句(7)
		System.out.println("count1:" + svt.getCount2());// 语句(8)
	}	
	
	public static int getCount1() {
		return count1;
	}

	public static void setCount1(int count1) {
		StaticVariableTest.count1 = count1;
	}

	public static int getCount2() {
		return count2;
	}

	public static void setCount2(int count2) {
		StaticVariableTest.count2 = count2;
	}
}

 

问题:当执行完语句(7)(8)时,打印结果分别是什么?为什么? 

解答:当执行完语句(7)时,打印结果是1,当执行完语句(8)时,打印结果是0。分析:程序执行从main方法开始,首先执行语句(6),调用 getInstance方法,然而当它去调用这个方法的时候,它是一个静态的方法,在这个类里面定义了多个静态的成员变量。根据java初始化的顺序我们知道,对于静态的内容肯定是先执行的,也就是说在执行getInstance方法之前,肯定先执行private static StaticVariableTest svt = new StaticVariableTest();而且它是从上到下分别执行静态的内容。换句话说,这个程序首先执行private static StaticVariableTest svt = new StaticVariableTest();而这里面又要调用一个构造方法StaticVariableTest(),则去执行这个构造方法 private StaticVariableTest(),执行这个构造方法时发现它里面的功能是将count1加1,将count2加1,而这个count1和 count2是我们定义的int类型的静态变量。根据java对成员变量的默认值,count1和count2初始化的时候都被设置为0,当执行完构造方法后count1和 count2都等于1,这时StaticVariableTest这个对象就生成了,已经在内存里面存在了。接着赋给svt这个引用。那么svt这个引用指向的StaticVariableTest类型的对象,它里面的count1是1,count2也是1。接着发现下面一行private static int count1;它是一个静态的,那么它要执行这行代码,这行代码只是一个声明,但是没有赋值,接着它就跳过这行不再赋值了(究其原因是因为count1已经被赋值了,已经被加1了,也就是count1为1)。当我执行private static int count2 = 0;时发现count2也是一个静态变量,而且有一个显示的去赋值的这样一个动作。我们知道count2已经被赋值1了,但是这儿有一个显示的赋值的动作,就把count2的值由1改变成了0。这个就是调用getInstance方法时程序的执行流程:语句(6)、语句(5)、语句(1)、语句(4)、语句(2)、语句(3) 

 

思考:如果将语句(2)和语句(3)放在语句(1)前面,当执行完语句(7)时,打印结果是1,当执行完语句(8)时,打印结果是1,想想是为什么?