例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、执行子类的构造函数
如果类已经被加载: 则静态代码块和静态变量就不用重复执行,再创建类对象时,只执行与实例相关的变量初始化和构造方法。
新闻热点
疑难解答