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笔记

posted @ 2016-04-23 18:02  iamzhoug37  阅读(423)  评论(0编辑  收藏  举报