Java classloader机制

JDK默认ClassLoader

1.Bootstrap loader

BootStrap加载器是用C++语言写的,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME/%jre/lib,-Xbootclasspath参数指定的路径以%JAVA_HOME%/jre/classes中的类。

2.ExtClassLoader

Bootstrap loader加载ExtClassLoader,并且将ExtClassLoader的父加载器设置为BootStrap loader。ExtClassLoader是用Java定的,具体来说就是sun.misc.Launcher$ExtClassLoader,ExtClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。

3.AppClassLoader

Bootstrap loader加载完ExtClassLoader后,就会加载AppClassLoader,并且将AppClassLoader的父加载器指定为ExtClassLoader,AppClassLoader也是用Java写成的,它的实现类是sun.misc.Launcher$AppClassLoader主要负责加载classpath所指定的位置的类或者jar文档,它也是Java程序默认的类加载器。

 

用户还可以自定义自己的ClassLoader,而这些自定义的ClassLoader都必须继承自java.lang.ClassLoader。

 

双亲委托模型(先由父类加载,增加共享)

 

Java中ClassLoader的加载采用了双亲委托机制,采用双亲委托机制加载类的时候采用如下的几个步骤:

  1. 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。

    每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。

  2. 当前classLoader的缓存中没有要加载的类时,请求父类去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.

  3. 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。

说到这里大家可能会想,Java为什么要采用这样的委托机制?理解这个问题,我们引入另外一个关于Classloader的概念“命名空间”, 它是指要确定某一个类,需要类的全限定名以及加载此类的ClassLoader来共同确定。也就是说即使两个类的全限定名是相同的,但是因为不同的 ClassLoader加载了此类,那么在JVM中它是不同的类。明白了命名空间以后,我们再来看看委托模型。采用了委托模型以后加大了不同的 ClassLoader的交互能力,比如上面说的,我们JDK本生提供的类库,比如hashmap,linkedlist等等,这些类由bootstrp 类加载器加载了以后,无论你程序中有多少个类加载器,那么这些类其实都是可以共享的,这样就避免了不同的类加载器加载了同样名字的不同类以后造成混乱。

 

 

 

自定义ClassLoader

1.继承java.lang.ClassLoader

2.重写父类的findClass方法。

为什么只重写findClass方法,这是因为JDK已经在loadClass方法中帮我们实现了ClassLoader搜索类的算法,当loadClass方法中搜索不到类时,loadClass方法就会调用findClass就去来搜索类。

 

最后欢迎大家访问我的个人网站:1024s

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值