刚看到一个帖子有这样一个程序: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个程序结果与原因

解决方案 »

  1.   

    程序一:
    因为属性都是静态的,所以会依次初始化……
    1.初始化属性obj ,在此之前属性counter1、 counter2、counter3都未显示初始化 故都为0;之后都为1
    2.再依次初始化counter1、 counter2 程序二的结果就可想而知了
      

  2.   


    private static Singleton obj = new Singleton(); 
    public  static int counter1=100; 你问的问题不在点上,就是按顺序执行么,这几个static的变量, obj需要调构造函数,总不可能绕过去先初始化几个static int变量吧
      

  3.   

    如果有静态变量,那么先构造静态变量,如果有多个静态变量那么按顺序初始化,实际上构造函数也相当于一个静态方法。
    上述Singleton obj = Singleton.getInstance(); 如果在前,则counter 1、2、3实际上并未被初始化只是被jvm
    都预初始化为0,而在后的则三个变量都已被初始化,为100,10,0 所以有上述的结果
      

  4.   

    是不是这个意思,第一种情况: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 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();
    最后才调到构造函数?
      

  5.   

    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 = 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=0
    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 = 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
    我改了一下,楼主看一下结果,应该就知道运行的顺序了。
      

  6.   

    顶楼上,因为构造函数和变量都是静态的,所以按顺序来的,你的两个顺序不一样,因此结果不一样,跟构造函数和静态变量的执行顺序没有关系,因为你现在用的是sigleton模式,所以构造函数为静态的。如果在普通的类里,肯定是先初始化静态变量,然后在运行期执行构造函数 。
      

  7.   

    先对静态变量初始化,然后再是函数
    构造函数默认就是静态static的
      

  8.   


    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; 
    } } 这不能说是类的加载问题,而是类的初始化,
    代码经过搬移,如上所示,是严格的按照你的静态变量和静态块的顺序来执行的
      

  9.   

    第一个代码块里counter3为什么是1而不是0啊
      

  10.   


    其实,这个是一个“数据(当然也包括构造函数)初始化问题”!具体的顺序是这样的:
           
          对于没有继承的情形----》
                                  
         先初始化静态的成员变量(域),然后再初始化非静态的成员变量,然后才是构造方法。若是有几个静态
    变量(或几个非静态的变量),不论其在什么位置(比如说有的在构造器之后),都是按顺序初始化的。     对于有继承的情形------》     上面的东西不变,只是在调用导出类的构造方法时,系统会先主动的向上到基类,一直到最顶层,然后一层层按上面没有继承的情形来进行初始化。
    至于上面提出的问题,是几个静态成员变量的初始化问题,当然是按照顺序来初始化了!要想很好的理解数据初始化,不妨参考《THINKING IN JAVA》第四版,P94-98,P159,P163.
      

  11.   

    Java 虚拟机会先把类中所有的变量名声明,然后才会按顺序赋值