构造方法调用顺序

http://blog.csdn.net/macheng365/article/details/6403050

http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html

http://blog.csdn.net/macheng365/article/details/6403050

 

其中:静态成员和Static块初始化按照出现的顺序,普通成员初始化和非static块也按照顺序。

父类上层还有父类时,总是先执行最顶层父类的Static-->派生类Static-->派生类Static-->.......-->子类Static-->顶层父类的其他成员变量-->父类构造方法--> 派生类的其他成员变量 --> 派生类构造方法--> ...............-->子类其他成员变量-->子类构造方法

public class Test04 ...{
    private static Test04 t1 = new Test04();
    private static int i1;
    private static int i2 = 2;
    
    public Test04()...{
        i1++;
        i2++;
    }
    
    public static void main(String[] args) ...{
        Test04 t2 = new Test04();
        System.out.println("t2.i1 = " + t2.i1);
        System.out.println("t2.i2 = " + t2.i2);
    }
}
我们先预计一下输出,可能有几种答案:2和3,3和3,2和2
执行代码后:
t2.i1 = 2
t2.i2 = 3

其实代码的执行顺序是这样的:首先执行给t1,i1,i2分别给予初始值null,0,0,再执行
Test04 t1 =new Test04(),这样i1++,i2++被执行,i1,i2都变为1,执行完毕后接着执行int i1; i1,i2的值仍然是1,1,当执行int i2 = 2时i2被赋予了值,即i1 = 1,i2=2;再执行Test04 t2 = new Test04(),i1,i2再执行++,此时i1 =2,i2 =3,输出i1,i2,结果就是:t2.i1 = 2,t2.i2 = 3。 通过上面的代码我们可以认为系统默认值的给予比通过等号的赋予先执行。再看个扩展的例子:

//A
class A{
        private static A t1 = new A();
        private static int i1;
        private static int i2 = 2;
        
        public static A getT1() {
            return t1;
        }

        public static void setT1(A t1) {
            A.t1 = t1;
        }

        public static int getI1() {
            return i1;
        }

        public static void setI1(int i1) {
            A.i1 = i1;
        }

        public static int getI2() {
            return i2;
        }

        public static void setI2(int i2) {
            A.i2 = i2;
        }

        public A(){
            i1++;
            i2++;
        }
    }  

//B
class B{
        
        private static int i1;
        private static int i2 = 2;
        private static B t1 = new B();
        //方法同上。。。。
    }  
//C
class C{
        
        private static int i1;
        private static C t1 = new C();
        private static int i2 = 2;
          //方法同上。。。。
    }  
//test
import static org.junit.Assert.*;
import org.junit.Test;
public class test {
    @Test
    public void testA(){
        A t2 = new A();
        assertEquals(t2.getI1(),2);
        assertEquals(t2.getI2(),3);
    }
    @Test
    public void testB(){
        B t2 = new B();
        assertEquals(t2.getI1(),2);
        assertEquals(t2.getI2(),4);
    }
    @Test
    public void testC(){
        C t2 = new C();
        assertEquals(t2.getI1(),2);
        assertEquals(t2.getI2(),3);
    }
    
}

 说明:要区别ABC的区别,主要注意静态成员变量的初始化顺序不同,

当private static A t1 = new A()执行之前,i1=0,i2=0;执行之后,i1=1,i2=1;之后执行private static int i1; private static int i2 = 2;i1=1,i2=2;之后A t2 = new A();

当private static B t1 = new B()执行之前,i1=0,i2=2;执行之后,i1=1,i2=3;B t2 = new B();

当private static C t1 = new C()执行之前,i1=0,i2=0;执行之后,i1=1,i2=1;private static int i2 = 2;i1=1,i2=2;C t2 = new C();

原文地址:https://www.cnblogs.com/seven7seven/p/3728687.html