java类加载机制的代码实例
package typeinfo; import java.util.Random; class Initable { static final int staticFinal = 47 ; static final int staticFinal2 = RandomInit.rand.nextInt(1000) ; static { System.out.println("initializing initable"); } } class Initable2 { static int staticNonFinal = 147 ; static { System.out.println("initializing initable2"); } } class Initable3 { static int staticNonFinal = 47 ; static { System.out.println("initializing initable3"); } } class RandomInit { public static Random rand = new Random(47) ; static { System.out.println("hello"); } } class Initable4 { static{ System.out.println("initable 4"); } static final double x = ClassInitialization.pi ; } class Initable5 { static{ System.out.println("initable 5"); } } public class ClassInitialization { static final double pi = 3.1415 ; public static void main(String[] args)throws Exception { System.out.println(Initable4.x); //由于x是编译时常量(常量表达式), 所以不会引起Initable4的初始化 System.out.println("----"); Class initable = Initable.class ; //不属于引起初始化的4种条件之一, 不会引起初始化 System.out.println("after creating initable ref") ; System.out.println(Initable.staticFinal);//staticFinal是编译时常量, 在解析时被替换成47, 不会引起初始化 System.out.println(Initable.staticFinal2);//staticFinal2不是编译时常量, 会引起初始化, 属于getstatic System.out.println(Initable2.staticNonFinal);//非常量, 引起初始化, 属于getstatic Class initable3 = Class.forName("typeinfo.Initable3") ;//会引起初始化, 但是不知道为什么 System.out.println("after creating initable3 ref"); System.out.println(Initable3.staticNonFinal); Initable5[] initable5s = new Initable5[10] ;//不属于那4中条件之一, 不初始化 } }
class SSClass { static { System.out.println("SSClass"); } } class SuperClass extends SSClass { static { System.out.println("SuperClass init!"); } public static int value = 123; public SuperClass() { System.out.println("init SuperClass"); } } class SubClass extends SuperClass { static { System.out.println("SubClass init"); } static int a; public SubClass() { System.out.println("init SubClass"); } } public class NotInitation { public static void main(String[] args) { System.out.println(SubClass.value);//由于是子类引用父类静态成员, 不属于初始化的那四种, 因此不会使SubClass初始化 } } /** * SSClass * SuperClass init! * 123 */
public class StaticTest { public static void main(String[] args) { staticFunction(); } static StaticTest st = new StaticTest(); static { System.out.println("1"); } { System.out.println("2"); } StaticTest() { System.out.println("3"); System.out.println("a="+a+",b="+b); } public static void staticFunction(){ System.out.println("4"); } int a=110; static int b =112; } /** * 使用了invokestatic(staticFunction()),因此要对StaticTest进行加载并初始化 * 初始化时, 先加载,验证, 然后准备(在这个阶段, st被赋值为null,b为0, 然后解析(这个实例什么都没干) * 最后执行初始化, 形成的cinit如下 * { * st = new Statictest() ; * System.out.println("1") ; * b = 112 ; * } * 只要连接阶段(验证, 准备,解析)一过, 其实整个类就可以使用了, 在执行new StaticTest时, 先将成员变量初始化 * 为0或null, 也就是a=0 , 然后再按照非静态代码块和成员变量的初始化顺序,依次执行初始化, 也就是先执行 * { * System.out.println("2"); * } * 然后执行a=110 ; * 最后执行 StaticTest() * { * System.out.println("3"); * System.out.println("a="+a+",b="+b); * } * * 所以总体的执行输出结果为 * 2 * 3 * a=110,b=0 * 1 * 4 */
//http://www.importnew.com/18548.html
//http://blog.csdn.net/java2000_wl/article/details/8040633
//thinking in java笔记