class Singleton {
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
} // 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
} 答案为什么是
obj.counter1==1
obj.counter2==0 求解呀!个人怀疑是一开始的Static int counter1;只是申明而没有定义。
而在Counter1++时,才给定了初值!
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
} // 程序2
public class MyMain {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=="+obj.counter1);
System.out.println("obj.counter2=="+obj.counter2);
}
} 答案为什么是
obj.counter1==1
obj.counter2==0 求解呀!个人怀疑是一开始的Static int counter1;只是申明而没有定义。
而在Counter1++时,才给定了初值!
http://blog.ccw.com.cn/qq/post/20050714/1300.htm
我是这么人为的,首先加载类的时候,首先给属性分配空间,然后再依次执行代码
class Singleton {
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
相当于
class Singleton {
//先分配空间
private static Singleton obj;
public static int counter1;
public static int counter2;
//然后执行静态代码
static {
obj = new Singleton(); //这里首先调用构造函数,因为属性counter1和counter2是static,所以被自动初始化为0
counter2 = 0;//调完构造函数后再执行赋值语句,所以counter2又变回0了
}
private Singleton() {
counter1++;
counter2++;
}
Singleton.counter1++;
Singleton.counter2++;
按照你编写的顺序代码是这样的
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
其关键在于 你是先 创建的静态对象private static Singleton obj = new Singleton();
而后覆盖了默认的构造函数
private Singleton() {
counter1++;
counter2++;
}
按照class初始化的顺序, private static Singleton obj = new Singleton(); 会先执行,此时的Singleton()应该还是类默认的构造函数,而不是你覆盖的那个。如果你把private static Singleton obj = new Singleton(); 这句代码写在
private Singleton() {
counter1++;
counter2++;
}
之后,程序输出结果就会变成
obj.counter1==1
obj.counter2==1PS:个人理解,仅供参考
1.在初始化类的时候,是按照标有关键字static的顺序初始化数据成员的。
2.然后初始化非static的数据成员
3.然后执行构造函数
本例中,最先开始声明obj,程序也会执行到你定义的构造函数,但是由于还没有执行到声明counter1和counter2,所以构造函数就会跳过。
如果想得到的结果是:
obj.counter1==1
obj.counter2==1
那么,有两种方法:
1.把声明counter1和counter2,放在obj前
2.初始化obj的工作,放在getInstance()方法里
obj.counter1==1
obj.counter2==0
试验如下(为了程序清楚起见,我更改了一下数值,以便更好的说明问题):
class Singleton {
private Singleton() {
counter1 = 10;
counter2 = 10;
System.out.println(counter1);
System.out.println(counter2);
}
private static Singleton obj = new Singleton(); public static int counter1; public static int counter2 = 20; public static Singleton getInstance() {
return obj;
}
}// 程序2
public class StaticTest {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1==" + obj.counter1);
System.out.println("obj.counter2==" + obj.counter2);
}
}
运行结果为:
10
10
obj.counter1==10
obj.counter2==20
可以看出在构造函数中的两个值都赋为10之后都打印出来了,但counter2在主程序中打印的时候值又会被20覆盖了.因此我认为阿宝的解释是正确的.
public static int counter1; public static int counter2 = 20;
private Singleton() {
counter1 = 10;
counter2 = 10;
System.out.println(counter1);
System.out.println(counter2);
}
private static Singleton obj = new Singleton();
打印结果又变成了:
10
10
obj.counter1==10
obj.counter2==10
说明语句的顺序对赋值的顺序也是有影响的.