[b]定义[/b]
java把类的数据从class文件加载到内存,并对数据进行校验、转换解析、初始化,形成最终可以被jvm使用的java类型,这个就是jvm的类加载机制。
[b]生命周期:[/b]
一个类的生命周期为:加载、验证、准备、解析、初始化、使用、卸载。其中,验证、准备、解析三个部分统称为连接(Linking)。
[b]类别:[/b]
java中执行类加载工作的就是classloader,java中类似中classloader,分别为引导类加载器,扩展类加载器,系统类加载器,自定义类加载器。jvm一启动,会形成三个类加载器,引导类加载器,扩展类加载器,系统类加载器,引导类加载器是jvm的一部分,一般由jnl实现,它负责加载/jre/lib/rt.jar、/jre/lib/jsse.jar等库类,系统已启动就把这些库类加载到jvm中。扩展类加载器负责加载加jre/lib/ext下面的jar,你也可以把你自己的jar放到该目录下进行加载,但是它不能引用类加载器加载的库类;系统类加载器负责在jvm启动时,加载classpath中指定的class或者库类。
[b]双亲委派:[/b]
类加载器加载类的过程是用了双亲委托的策略进行加载的,就是说递归先尝试从父加载器中进行加载,也就是最终先是引导类加载器最新尝试加载,如果不成功,就尝试从扩展类加载器,然后是系统加载器。
在双亲委派模型中,一个类加载器委派的对象是它的双亲,它的双亲再委派给它的双亲,这是一个递归的过程,大多数情况下,委派的末端就是引导类加载器,如果一个双亲加载器加载失败了,控制权再回到子加载器,如果加载链中的某个加载器成功加载的该类型,该加载器就是该类型的定义类加载器,这个定义类装载器和委派过程中排在它前面的装载器都被标记为这个类型的初始类加载器,这个类也就被加到这些初始类加载器的加载类维护表中(对于每一个加载器,在jvm中都维护一张表,记录了所有以其为初始类加载器的类型的名字),每一张这样的表就组成了jvm内部的类的命名空间。
[b]破坏双亲委派:[/b]
双亲委派模式很好的解决了各个类加载器的基础类的统一问题,越基础的类由越上层的加载器加载,也保证了基础类的安全性,但是如果基础类又要调用用户的类,怎么办?这种场景也经常出现,比如jndi服务,它的代码由启动类去加载,但是实现由各个独立厂商的api去实现,这里实现程序放在classpath,启动类加载器加载不到的地方,这个就需要Thread类中的contextClassLoader来帮忙,如果线程创建是,它还未设置,它将从父线程中继承一个,如果整个应用都没有被设置过,这个类加载器默认就是系统类加载器。
查看类加载信息:verboer:class
java把类的数据从class文件加载到内存,并对数据进行校验、转换解析、初始化,形成最终可以被jvm使用的java类型,这个就是jvm的类加载机制。
[b]生命周期:[/b]
一个类的生命周期为:加载、验证、准备、解析、初始化、使用、卸载。其中,验证、准备、解析三个部分统称为连接(Linking)。
[b]类别:[/b]
java中执行类加载工作的就是classloader,java中类似中classloader,分别为引导类加载器,扩展类加载器,系统类加载器,自定义类加载器。jvm一启动,会形成三个类加载器,引导类加载器,扩展类加载器,系统类加载器,引导类加载器是jvm的一部分,一般由jnl实现,它负责加载/jre/lib/rt.jar、/jre/lib/jsse.jar等库类,系统已启动就把这些库类加载到jvm中。扩展类加载器负责加载加jre/lib/ext下面的jar,你也可以把你自己的jar放到该目录下进行加载,但是它不能引用类加载器加载的库类;系统类加载器负责在jvm启动时,加载classpath中指定的class或者库类。
[b]双亲委派:[/b]
类加载器加载类的过程是用了双亲委托的策略进行加载的,就是说递归先尝试从父加载器中进行加载,也就是最终先是引导类加载器最新尝试加载,如果不成功,就尝试从扩展类加载器,然后是系统加载器。
在双亲委派模型中,一个类加载器委派的对象是它的双亲,它的双亲再委派给它的双亲,这是一个递归的过程,大多数情况下,委派的末端就是引导类加载器,如果一个双亲加载器加载失败了,控制权再回到子加载器,如果加载链中的某个加载器成功加载的该类型,该加载器就是该类型的定义类加载器,这个定义类装载器和委派过程中排在它前面的装载器都被标记为这个类型的初始类加载器,这个类也就被加到这些初始类加载器的加载类维护表中(对于每一个加载器,在jvm中都维护一张表,记录了所有以其为初始类加载器的类型的名字),每一张这样的表就组成了jvm内部的类的命名空间。
[b]破坏双亲委派:[/b]
双亲委派模式很好的解决了各个类加载器的基础类的统一问题,越基础的类由越上层的加载器加载,也保证了基础类的安全性,但是如果基础类又要调用用户的类,怎么办?这种场景也经常出现,比如jndi服务,它的代码由启动类去加载,但是实现由各个独立厂商的api去实现,这里实现程序放在classpath,启动类加载器加载不到的地方,这个就需要Thread类中的contextClassLoader来帮忙,如果线程创建是,它还未设置,它将从父线程中继承一个,如果整个应用都没有被设置过,这个类加载器默认就是系统类加载器。
查看类加载信息:verboer:class