1、
2、
①BootStrap ClassLoader:启动类的类加载器,负责加载jdk放在li目录下的文件,是一个能够被虚拟机识别的类
②Extension ClassLoader:扩展加载器,主要负责加载jre目录下的ext的目录,可以直接使用这个类加载器
③APP ClassLoader:应用程序的类加载器,它负责加载用户目录下可执行的类,这个类加载器也可以被直接使用
④BootStrap ClassLoader不继承classloader这个类,因为它不是一个普通的java类,它底层是用c++编写的
3、
4、
①启动类加载器执行完成之后,所有的其它类加载器才可以使用,这就是双亲委托模型
②上方是启动类加载器,下方是扩展类加载器,再下方是应用程序类加载器,最底部是自定义类加载器,这种层次关系就称为类加载器的双亲委托模型。我们把每一层上方的类加载器,叫做当前类加载器的父加载器。它们之间的父子关系并不是通过继承来实现的,而是通过组合关系来复用父加载器中的代码。
工作流程很简单,比如一个类加载器收到了加载java的.class文件的要求,它首先不会尝试自己去加载这个类,它会请求委托给父加载器来完成,一直向上,所有的类加载器请求最终都应该被传递到顶层的启动类加载器当中。只有父加载器在它的搜索范围之内没有找到它所需要的类时,这时候它无法完成加载,这时它的子加载器才会尝试去加载这个类。使用双亲委托模型,能阻滞类加载器之间的关系,它有一个明显的好处就是,java类随着它的类加载器,一起具备了一种层次关系,这对于保证java程序的稳定性非常重要。
③总结:当一个classloader实例需要去加载某一个类时,会在试图亲自加载某个类之前,把这个任务交给它的父类加载器,这个过程是由上至下依次检查的。它首先由最顶层的类加载器也就是bootclassloader试图加载,如果没有加载到,就把任务交给扩展类加载器去加载,如果也没有加载到,就把它交给app应用程序类加载器来进行加载,如果也没有加载到的话就交给委托的发起者,这就是双清委托模型的工作流程
5、类加载的过程
①加载-->验证-->准备-->初始化过程都是确定的,但是解析的过程是不确定的。它在某些情况下可以在初始化阶段之后开始。这是为了支持java语言的动态绑定。
②使用、卸载是在所有顺序定了之后才执行
6、静态绑定与动态绑定
静态绑定:程序执行以前,这个方法就被绑定了,此时是由编译器连接这个方法
动态绑定:运行时绑定,运行时根据具体的对象类型来进行的绑定
7、类加载的过程:
①
②
③
基本数据类型如果没有显式地赋值,那么系统就会为其默认赋值。对于局部变量,在使用前必需为其赋值,否则编译不通过。
被static和final修饰的变量必需显式地为其赋值,否则编译不通过。如果变量仅仅是被final修饰,那么可以在声明的时候显示地为它赋值,也可以在类初始化的时候为其赋值。总之,被final修饰的变量,一定要在使用前显示地为其赋值,否则系统不会为它赋默认值。
对于引用数据类型的reference,比如常说的数组引用、对象引用等等,如果没有对其显示地赋值,而直接使用,那么系统将会给它赋默认值
如果数组对象初始化时没有赋值,也会根据对应的类型赋默认值
④
对类和方法的解析都是先搜索父类,再搜索接口
接口只递归向上搜索解析
⑤这一步才是真正执行java中类的代码的过程
在准备阶段,类已经被初始化过了
整个类的加载过程,除了加载用户应用程序可以自定义加载器之外,其余所有动作都是由虚拟机主导和控制的,到了初始化才开始执行代码中字节码。这里的执行代码只是开端,仅限于构造器。类加载过程主要是将.class文件(二进制字节流)加载到虚拟机内存当中,真正执行字节码的操作,在开始完成加载之后才执行。