初步了解 Java类加载子系统

        Java虚拟机中的类加载器分为两种:原始类加载器(primordial class loader)和类加载器对象(class loaderobjects)。原始类加载器是Java虚拟机实现的一部分,类加载器对象是运行中程序的一部分。不同类加载器加载的类被不同的命名空间所分割。

类加载器调用了许多Java虚拟机中其他的部分和java.lang包中的很多类。比如,类加载对象就是java.lang.ClassLoader子类的实例,ClassLoader类中的方法可以访问虚拟机中的类加载机制;每一个被Java虚拟机加载的类都会被表示为一个java.lang.Class类的实例。像其他对象一样,类加载器对象和Class对象都保存在堆中,被加载的信息保存在方法区中。

1、加载、连接、初始化(Loading,Linking and Initialization

类加载子系统不仅仅负责定位并加载类文件,他按照以下严格的步骤作了很多其他的事情:

1)、加载:寻找并导入指定类型(类和接口)的二进制信息

2)、连接:进行验证、准备和解析

①验证:确保导入类型的正确性

②准备:为类型分配内存并初始化为默认值

③解析:将字符引用解析为直接饮用

3)、初始化:调用Java代码,初始化类变量为合适的值

2、原始类加载器(The PrimordialClass Loader

每个Java虚拟机都必须实现一个原始类加载器,他能够加载那些遵守类文件格式并且被信任的类。但是,Java虚拟机的规范并没有定义如何加载类,这由 Java虚拟机实现者自己决定。对于给定类型名的类型,原始莱加载器必须找到那个类型名加“.class”的文件并加载入虚拟机中。

3、类加载器对象

虽然类加载器对象是Java程序的一部分,但是ClassLoader类中的三个方法可以访问Java虚拟机中的类加载子系统。

1)、protected final ClassdefineClass():使用这个方法可以出入一个字节数组,定义一个新的类型。

2)、protected ClassfindSystemClass(String name):加载指定的类,如果已经加载,就直接返回。

3)、protected final voidresolveClass(Class c)defineClass()方法只是加载一个类,这个方法负责后续的动态连接和初始化。

4、命名空间

当多个类加载器加载了同一个类时,为了保证他们名字的唯一性,需要在类名前加上加载该类的类加载器的标识。具体的信息,参见第八章“连接模型”( The Linking Model)。

为了更好的了解类加载的过程,我们一起来看看下面的案例吧!

案例1

class Singleton{

    private static Singleton singleton=new Singleton ();

    public static int count1;

    public static int count2=0;

    private Singleton(){

       System.out.println("12345");

       count1++;

       count2++;

    }

    static{

       System.out.println("efefewferfte");

       count1++;

       count2++;

    }

    public static SingletongetInstance(){

       return singleton;

    }

}

public class MyTest{

    public static void main(String[]args){

       System.out.println("count1="+ Singleton.count1);

       System.out.println("count2="+ Singleton.count2);

    }

}

案例2

class Singleton1{

    public static int count1;

    public static int count2=0;

    private static Singleton1 singleton=new Singleton1();

    private Singleton1(){

       System.out.println("构造方法...");

       count1++;

       count2++;

    }

    public static Singleton1getInstance(){

       return singleton;

    }

    static{

       System.out.println("静态方法...");

    }

}

public class MyTest1{

    public static void main(String[]args){

       System.out.println("count1="+ Singleton1.count1);

       System.out.println("count2="+ Singleton1.count2);

    }

}

案例3

class FinalTest1{

    public static final int count=6/3;

    static{

       System.out.println("静态块"+count);

    }

    private FinalTest1(){

       System.out.println("构造方法:"+count);

    }

}

 

public class MyTest2{

    public static void main(String[]args){

       System.out.println("count1="+ FinalTest1.count);    

    }

}

案例4

class FinalTest2{

    public static final int count=newRandom().nextInt(100);

    static{

       System.out.println("静态块");

    }

    private FinalTest2(){

       System.out.println("构造方法");

    }

}

public class MyTest3{

    public static void main(String[]args){

       System.out.println("count1="+ FinalTest2.count);

    }

}

    乍一看,好像案例1和案例2,案例3和案例4没什么很大的区别,但结果小伙伴们预料到了吗?想想为什么会这样呢?

参考:http://blog.csdn.net/witsmakemen/article/details/28600127

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值