Java类加载的执行顺序

一. 类初始化

首先定义测试类Test.java,定义静态变量、代码块、静态代码块、构造函数和静态方法 :

package org.test.classload;

public class Test {
    public static int static_var = 10;

    static {
        static_var += 10;
        System.out.println("Test       static block static_var: " + static_var);
    }

    public Test(){
        static_var += 10;
        System.out.println("Test       variable static_var: " + static_var);
    }

    public static void print(){
        static_var += 10;
        System.out.println("Test       Function static_var: " + static_var);
    }

    {
        static_var += 10;
        System.out.println("Test       block static_var: " + static_var);
    }
}

然后调用Test类中静态方法:

package org.test.classload;

public class Main {
    public static void main(String[] args){
        Test.print();
    }
}

结果为:

Test       static block static_var: 20
Test       Function static_var: 30

从结果中可以看到静态块中的static_var的值是10,证明这时候静态变量static_var是已经完成了赋值的,所以加载优先级应该是 静态变量>静态代码块

二. 类实例化

由于上述例子中该类没有被实例化的,我们看不到非静态块和构造方法的加载表现。接下来,我们修改Main类中的代码,来测试非静态块和构造函数的加载顺序。

package org.test.classload;

public class Main {
    public static void main(String[] args){
        Test test = new Test();
        Test.print();
    }
}

结果为:

Test       static block static_var: 20
Test       block static_var: 30
Test       variable static_var: 40
Test       Function static_var: 50

在这里,我们可以看到,首先静态变量被初始赋值为10;然后执行静态块,值变为20;接下来执行非静态块的代码,值再加10;当以上完成之后,类加载完成才开始实例化对象,执行类的构造函数。所以,我们判断执行优先级是 静态变量>静态代码块>代码块>构造函数

三. 全局变量

现在我们在Test类中添加非静态的全局变量及其赋值方法,观察该变量在类加载过程中,静态变量的赋值。

Test.java
package org.test.classload;

public class Test {
    public static int static_var = getStaticValue();
    public int var = getValue();

    public static int getStaticValue(){
        static_var += 10;
        System.out.println("Test       getStaticValue: " + static_var);
        return static_var;
    }

    public int getValue(){
        static_var += 10;
        System.out.println("Test       getValue: " + static_var);
        return static_var;
    }

    static {
        static_var += 10;
        System.out.println("Test       static block static_var: " + static_var);
    }

    public Test(){
        static_var += 10;
        System.out.println("Test       variable static_var: " + static_var);
    }

    public static void print(){
        static_var += 10;
        System.out.println("Test       Function static_var: " + static_var);
    }

    {
        static_var += 10;
        System.out.println("Test       block static_var: " + static_var);
    }
}
Main.java
package org.test.classload;

public class Main {
    public static void main(String[] args){
        Test test = new Test();
    }
}

结果为:

Test       getStaticValue: 10
Test       static block static_var: 20
Test       getValue: 30
Test       block static_var: 40
Test       variable static_var: 50

这里可以看到,这里执行的优先级依次是,静态变量初始化>静态块>全局变量初始化>非静态块>构造函数

四. 静态变量之间的顺序

定义三个静态全局变量,给中间变量赋值,然后在前后两个变量初始化方法中设置取中间变量的方法。具体代码如下所示:

Test.java
package org.test.classload;

public class Test {
    public static Test instance1 = new Test("instance1");

    public static int static_var = 10;

    public static Test instance2 = new Test("instance2");

    public static void getValue(){
        System.out.println("Test       getValue static_var: " + static_var);
    }

    public Test(String name){
        System.out.println("Test       " + name + " Constructor static_var: " + static_var);
    }
}
Main.java
package org.test.classload;

public class Main {
    public static void main(String[] args){
        Test.getValue();
    }
}

执行结果如下所示:

Test       instance1 Constructor static_var: 0
Test       instance2 Constructor static_var: 10
Test       getValue static_var: 10

可以看到静态变量是按照从上往下顺序初始化的

你可能感兴趣的:(Java类加载的执行顺序)