Java类加载顺序

来源:互联网 发布:js保留三位小数 编辑:程序博客网 时间:2024/05/01 14:34

例1:

public class StaticTest {    public static int k = 0;    public static StaticTest t1 = new StaticTest("t1");    public static StaticTest t2 = new StaticTest("t2");    public static int i = print("i");    public static int n = 99;    public int j = print("j");    {        print("构造快");    }    {        print("静态块");    }    public StaticTest(String str) {        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);        ++n;        ++i;    }    public static int print(String str) {        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);        ++i;        return ++n;    }    public static void main(String[] args) {        StaticTest t = new StaticTest("init");    }}

结果:
1:j i=0 n=0
2:构造快 i=1 n=1
3:静态块 i=2 n=2
4:t1 i=3 n=3
5:j i=4 n=4
6:构造快 i=5 n=5
7:静态块 i=6 n=6
8:t2 i=7 n=7
9:i i=8 n=8
10:j i=9 n=99
11:构造快 i=10 n=100
12:静态块 i=11 n=101
13:init i=12 n=102

类加载顺序:
* 1.加载类的静态属性(非静态不管)
* 这里加载的是:public static int k = 0;
* 然后加载:public static StaticTest t1 = new StaticTest(“t1”);
* 因为此处进行了类的实例化所以
* 1.1加载类的非静态属性
* 这里是:public int j = print(“j”);
* 运行完这个方法接着
* 1.2顺序加载类中的非static代码块(static暂时不加载)
* 这里是:print(“构造快”);和print(“静态块”);
* 运行完接着
* 1.3加载类的构造方法
* 这里是:public StaticTest(String str)
* 运行完(一个静态属性的实例就完成了)
* 2.继续加载类的静态属性
* 这里加载的是:public static StaticTest t2 = new StaticTest(“t2”);
* 2.1重复(1.1-1.3)
* 3.继续加载类的静态属性
* 这里加载的是:public static int i = print(“i”);
* 运行完接着
* 4.继续加载类的静态属性
* 这里加载的是:public static int n = 99;
* 不管你n原来是多少现在为99
* 接着
* 5.(如果有static代码块,在这里先加载,这个里面没有所以加载主函数)加载主函数
* 这里加载的是:StaticTest t = new StaticTest(“init”);
* 因为此处进行了类的实例化所以
* 5.1
* 重复1.1-1.3
* 5.2
* 因为public static int print(String str)这个方法返回++n
* 所以n从99开始累
* 运行完OK了

例2:

public class test {                         //1.准备加载类    public static void main(String[] args) {        new test();                                  }    static int num = 4;                    //2.静态变量和静态代码块的加载顺序由编写先后决定     {        num += 3;        System.out.println("b");           //4.按照顺序加载匿名代码块和非静态变量    }    int a =5;                              //5.按照顺序加载匿名代码块和非静态变量    {         System.out.println("c");           //6.按照顺序加载匿名代码块和非静态变量    }    test() {         System.out.println("d");           //7.最后加载构造函数,完成对象的建立    }    static {                               //3.静态变量和静态代码块的加载顺序由编写先后决定        System.out.println("a");    }    static void run()                      // 静态方法,调用的时候才加载// 注意看,e没有加载    {        System.out.println("e");    }}

一般顺序:静态块(静态变量)–>成员变量(匿名代码块)–>构造方法–>静态方法(调用的时候才加载)

例3:

public class Parent{     public static Print obj1 = new Print("1");     public Print obj2 = new Print("2");     public static Print obj3 = new Print("3");     static{         new Print("4");     }     public static Print obj4 = new Print("5");     public Print obj5 = new Print("6");     public Parent(){         new Print("7");     } }
public class Child extends Parent{     static{         new Print("a");     }     public static Print obj1 = new Print("b");     public Print obj2 = new Print("c");     public Child (){         new Print("d");     }     public static Print obj3 = new Print("e");     public Print obj4 = new Print("f");     public static void main(String [] args){         Parent obj1 = new Child ();         Parent obj2 = new Child ();     } }

执行main方法,程序输出顺序为: 1 3 4 5 a b e 2 6 7 c f d 2 6 7 c f d

如果有继承关系:

如果类还没有被加载:
1、先执行父类的静态代码块和静态变量初始化,并且静态代码块和静态变量的执行顺序只跟代码中出现的顺序有关。
2、执行子类的静态代码块和静态变量初始化。
3、执行父类的实例变量初始化
4、执行父类的构造函数
5、执行子类的实例变量初始化
6、执行子类的构造函数

如果类已经被加载:
则静态代码块和静态变量就不用重复执行,再创建类对象时,只执行与实例相关的变量初始化和构造方法。

1 0
原创粉丝点击