刚看到一个帖子有这样一个程序: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);
System.out.println("obj.counter3="+obj.counter3);
}
} class Singleton{
private static Singleton obj = new Singleton();
public static int counter1=100;
public static int counter2 = 10;
public static int counter3; private Singleton(){
counter1++; counter2++; counter3++; } public static Singleton getInstance(){ return obj;
} } 结果为:
obj.counter1=100
obj.counter2=10
obj.counter3=1但如果换下: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);
System.out.println("obj.counter3="+obj.counter3);
}
} class Singleton{ public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
private static Singleton obj = new Singleton();
private Singleton(){
counter1++; counter2++; counter3++; } public static Singleton getInstance(){ return obj;
} }
结果则为:
obj.counter1=101
obj.counter2=11
obj.counter3=1我有点糊涂了,生成Singleton对象obj时到底是先执行构造函数还是先对静态变量初始化,请高手解释下这2个程序结果与原因
public static void main(String[] args){
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1="+obj.counter1);
System.out.println("obj.counter2="+obj.counter2);
System.out.println("obj.counter3="+obj.counter3);
}
} class Singleton{
private static Singleton obj = new Singleton();
public static int counter1=100;
public static int counter2 = 10;
public static int counter3; private Singleton(){
counter1++; counter2++; counter3++; } public static Singleton getInstance(){ return obj;
} } 结果为:
obj.counter1=100
obj.counter2=10
obj.counter3=1但如果换下: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);
System.out.println("obj.counter3="+obj.counter3);
}
} class Singleton{ public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
private static Singleton obj = new Singleton();
private Singleton(){
counter1++; counter2++; counter3++; } public static Singleton getInstance(){ return obj;
} }
结果则为:
obj.counter1=101
obj.counter2=11
obj.counter3=1我有点糊涂了,生成Singleton对象obj时到底是先执行构造函数还是先对静态变量初始化,请高手解释下这2个程序结果与原因
因为属性都是静态的,所以会依次初始化……
1.初始化属性obj ,在此之前属性counter1、 counter2、counter3都未显示初始化 故都为0;之后都为1
2.再依次初始化counter1、 counter2 程序二的结果就可想而知了
private static Singleton obj = new Singleton();
public static int counter1=100; 你问的问题不在点上,就是按顺序执行么,这几个static的变量, obj需要调构造函数,总不可能绕过去先初始化几个static int变量吧
上述Singleton obj = Singleton.getInstance(); 如果在前,则counter 1、2、3实际上并未被初始化只是被jvm
都预初始化为0,而在后的则三个变量都已被初始化,为100,10,0 所以有上述的结果
public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
先执行private static Singleton obj = new Singleton();,完后跳到构造函数执行,返回来再执行
public static int counter1=100;
public static int counter2 = 10;
public static int counter3; 而第二种情况:public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
private static Singleton obj = new Singleton();先执行
public static int counter1=100;
public static int counter2 = 10;
public static int counter3;
再执行private static Singleton obj = new Singleton();
最后才调到构造函数?
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1=" + obj.counter1);
System.out.println("obj.counter2=" + obj.counter2);
System.out.println("obj.counter3=" + obj.counter3);
}
}class Singleton {
private static Singleton obj = new Singleton();
public static int counter1 = print(100, "counter1"); public static int counter2 = print(10, "counter2"); public static int counter3 = print(0, "counter3");
private Singleton() {
System.out.println("Singleton");
counter1++;
System.out.println("Inner Constructor counter1: " + counter1);
counter2++;
System.out.println("Inner Constructor counter2: " + counter2);
counter3++;
System.out.println("Inner Constructor counter3: " + counter3);
} public static Singleton getInstance() { return obj;
}
public static int print(int x, String s) {
System.out.println("Outer Constructor " + s + ": " + x);
return x;
}}
Singleton
Inner Constructor counter1: 1
Inner Constructor counter2: 1
Inner Constructor counter3: 1
Outer Constructor counter1: 100
Outer Constructor counter2: 10
Outer Constructor counter3: 0
obj.counter1=100
obj.counter2=10
obj.counter3=0public 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);
System.out.println("obj.counter3=" + obj.counter3);
}
}class Singleton {
public static int counter1 = print(100, "counter1"); public static int counter2 = print(10, "counter2"); public static int counter3 = print(0, "counter3");
private static Singleton obj = new Singleton(); private Singleton() {
System.out.println("Singleton");
counter1++;
System.out.println("Inner Constructor counter1: " + counter1);
counter2++;
System.out.println("Inner Constructor counter2: " + counter2);
counter3++;
System.out.println("Inner Constructor counter3: " + counter3);
} public static Singleton getInstance() { return obj;
}
public static int print(int x, String s) {
System.out.println("Outer Constructor " + s + ": " + x);
return x;
}}
Outer Constructor counter1: 100
Outer Constructor counter2: 10
Outer Constructor counter3: 0
Singleton
Inner Constructor counter1: 101
Inner Constructor counter2: 11
Inner Constructor counter3: 1
obj.counter1=101
obj.counter2=11
obj.counter3=1我改了一下,楼主看一下结果,应该就知道运行的顺序了。
构造函数默认就是静态static的
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);
System.out.println("obj.counter3="+obj.counter3);
}
} class Singleton{ public static int counter1; //1:counter1为0,默认的是0
public static int counter2; //同上
public static int counter3; //同上
private static Singleton obj; //为NULL
static{
counter1=100;//count1赋值为100
counter2=10;//count2赋值为10
obj = new Singleton(); //调用构造函数,三个域都加一,所以结果为101,11,1
}
private Singleton(){
counter1++; counter2++; counter3++; } public static Singleton getInstance(){ return obj;
} } 这不能说是类的加载问题,而是类的初始化,
代码经过搬移,如上所示,是严格的按照你的静态变量和静态块的顺序来执行的
其实,这个是一个“数据(当然也包括构造函数)初始化问题”!具体的顺序是这样的:
对于没有继承的情形----》
先初始化静态的成员变量(域),然后再初始化非静态的成员变量,然后才是构造方法。若是有几个静态
变量(或几个非静态的变量),不论其在什么位置(比如说有的在构造器之后),都是按顺序初始化的。 对于有继承的情形------》 上面的东西不变,只是在调用导出类的构造方法时,系统会先主动的向上到基类,一直到最顶层,然后一层层按上面没有继承的情形来进行初始化。
至于上面提出的问题,是几个静态成员变量的初始化问题,当然是按照顺序来初始化了!要想很好的理解数据初始化,不妨参考《THINKING IN JAVA》第四版,P94-98,P159,P163.