搜索类似解释只取几个情况说明加载循序。不够全面,看晕了眼,“有时静态块先执行,有时代码块先执行” 这样看似的谬论。
卒!自己Debug下结论。
例一
加载类时主基调:
②静态块、静态属性位置靠前的先执行。
③只有new对象时才会有 构造块>构造函数 (注意看⑤)
④构造块、构造函数只有new对象时才加载
⑤静态相关同一个类只加载一次
代码段
public class Test { { System.out.println("构造块1"); } static{ System.out.println("静态块1"); } public static Test t1 = new Test(); Test(){ System.out.println("构造函数"); }; public static Test t2 = new Test(); static{ System.out.println("静态块2"); } { System.out.println("构造块2"); } public static void main(String[] args) { System.out.println("测试1"); Test t = new Test(); System.out.println("测试2"); } }
执行结果(不需要解释了看最上面的结论足矣)
静态块1 构造块1 构造块2 构造函数 构造块1 构造块2 构造函数 静态块2 测试1 构造块1 构造块2 构造函数 测试2
----------------------------附加讨论 分割线-------------------------
例二
继承类关系的加载(需要明白上述问题再来看这个问题)
①首先先加载父类的那一套,但遵循上述的的主基调。
②加载类注意的是:先加载父类的静态相关 > 再加载子类的静态相关
③new对象时:先加载父类的构造块> 父类的构造函数 >再加载子类的构造块> 子类的构造函数 (同样的此过程不加载静态相关)
class Foo{ { System.out.println("foo构造块1"); } static{ System.out.println("foo静态块1"); } Foo(){ System.out.println("foo构造函数"); }; static{ System.out.println("foo静态块2"); } { System.out.println("foo构造块2"); } } public class Test extends Foo { { System.out.println("构造块1"); } static{ System.out.println("静态块1"); } public static Test t1 = new Test(); Test(){ System.out.println("构造函数"); }; public static Test t2 = new Test(); static{ System.out.println("静态块2"); } { System.out.println("构造块2"); } public static void main(String[] args) { System.out.println("测试1"); Test t = new Test(); System.out.println("测试2"); }
执行结果( 首先明白第一个例子,再琢磨这个例子 )
foo静态块1 foo静态块2 静态块1 foo构造块1 foo构造块2 foo构造函数 构造块1 构造块2 构造函数 静态块2 测试1 foo构造块1 foo构造块2 foo构造函数 构造块1 构造块2 构造函数 测试2