类加载器

类加载的第一个阶段,也是唯一开放给用户操作的阶段,通过一个全限定名来获取描述此类的2进制流
对于任意一个类,相等的前提是使用同一个类加载器加载,并且加载的同一个class。对于class的equals,isassignalefrom,isinstance,以及instanceof关键字
启动类加载器,加载java_home\lib下或者-xbootclasspath参数指定的路径的虚拟机能识别的class
其他classloader都继承抽象类java.lang.classloader
扩展类加载器加载\lib\ext或者环境变量java.ext.dirs指定的class
系统类加载器,即应用程序类加载器,由是classloader中getsystemclassloader的返回值,加载classpath下的class
开发者可直接使用扩展和系统类加载器,还可以自定义
标准的双亲委派,除启动类加载器外,都有父加载器,收到加载请求是时,先委托父类加载器加载,加载不到,才自己加载,通过组合而不是继承实现,保证了基础行为的正确性,实现代码主要在loadclass方法中,首先检查是否加载过,如没有则让父加载器加载,如报classnotfound异常,则使用findclass自己加载
3次破坏双亲委派
1在双亲委派出现前,自定义的类加载器直接覆盖load方法,在1.2之后建议直接覆盖findclass,这样保证会符合双亲委派
2当基础类需要回掉用户classpath下的类时,通过线程类加载器,通过thread类的setcontextclassloader来指定,如果创建线程时未指定,会从父线程继承一个,如果在应用程序范围内没指定过,则就是系统类加载器,这样相当于从父类加载器到请求子加载器加载,java所有涉及spi的动作都使用这种方式
3代码热替换,模块热部署,osgi实现模块化部署的关键是每一个程序模块bundle都有自己的类加载器,当收到类加载请求时, 1将以java.开头的类交给父类加载器 2否则将委派列表名单中的类交给父类加载器 3否则将import列表中的类交给exporter类的bundle的类加载器 4否则查找当前bundle的classpath,使用自己的类加载器加载 5否则查找是否在自己的fragment bundle中,委派给fragment bundle的类加载器 6否则查找dynamic import列表,交给相应的类加载器 7查找失败

你可能感兴趣的:(类加载器)