美文网首页
类的初始化顺序

类的初始化顺序

作者: 大飞_YEah | 来源:发表于2018-03-27 00:53 被阅读0次

    类的初始化顺序

    这几天看java编程思想内部类这节时,其中有个例子(第4版213页)的输出跟自己的预期有点出入,手动debug了一遍,发现是自己对类的初始化顺序理解不到位,于是重新将类的初始化顺序梳理了一番。

    话不多说,先看结论:

    • 父类静态域 > 子类静态域 > 父类非静态域 > 父类构造函数 > 子类非静态域 > 子类构造函数。
    • 如果有多个静态域或多个非静态域,则按声明顺序依次执行。
    • 当第一次调用静态函数时,会触发其他静态域的初始化,然后再执行该函数中的代码。

    证明示例如下:

    首先,来看没有继承的情况

    
    public class TestClassInit {
        public static void main(String[] args) {
            new Test(); 
        }
    }
    
    class A{
        public A(int i){
            System.out.println("("+i+")");
        }
    }
    
    class Test{
        static {
            System.out.println("静态块1...");
        }
        {
            System.out.println("非静态块1...");
        }
        static A a1 = new A(1);
        A a2 = new A(2);
    
        {
            System.out.println("非静态块2...");
        }
        A a3 = new A(3);
        static {
            System.out.println("静态块2...");
        }
        static A a4 = new A(4);
    
        static void f(){
            System.out.println("f()");
        }
    }
    
    
    
    
    

    输出结果为:

    静态块1...
    (1)
    静态块2...
    (4)
    非静态块1...
    (2)
    非静态块2...
    (3)

    将上述代码稍作改动,new Test(); 换成Test.f();

    输出结果为:

    静态块1...
    (1)
    静态块2...
    (4)
    f()

    再看有继承的情况

    
    public class TestClassInitWithExtend {
        public static void main(String[] args) {
            new Son();
        }
    }
    
    class Parent{
        public Parent(){
            System.out.println("New Parent()");
        }
        A a1 = new A (1);
        static A a2 = new A(2);
    
    }
    
    class Son extends Parent{
        public Son(){
            System.out.println("New Son()");
        }
        static A a3 = new A(3);
        A a4 = new A(4);
    }
    
    
    
    

    输出结果为:

    (2)
    (3)
    (1)
    New Parent()
    (4)
    New Son()

    相关文章

      网友评论

          本文标题:类的初始化顺序

          本文链接:https://www.haomeiwen.com/subject/qjadcftx.html