-
类加载过程
类加载过程:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。
一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 loadClass() 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。
所有的类都由类加载器加载,加载的作用就是将 .class文件加载到内存。
-
类加载器的作用
根据一个类的限定名来读取此类的二进制字节流到JVM中,然后转换为一个与目标类对应的java.lang.Class对象实例。
-
双亲委派模型
双亲委派模型是不同的类加载器之间的一种层次关系
双亲委派模型的工作过程:当一个类加载器收到了类加载的请求,它首先不会自己尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求(他的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
使用双亲委派模型的好处:- 保证了Java程序的稳定运行,可以避免类的重复加载(JVM区分不同的类的方式不仅仅根据类名,相同的类文件通过不同的类加载器加载产生的是两个不同的类)。
- 保证了Java核心API不被篡改
如果不用没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object 类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类。
-
Java虚拟机如何判断两个类相同
Java虚拟机不仅要看类的全名是否相同(含包名路径),而且还要看加载此类的类加载器是否相同,只有两者都相同的情况下才认为这两个类是相同的。
-
双亲委派模型的破坏者——线程上下文类加载器(Thread Context Classloader)
使用线程上下文类加载器,可以在执行线程中抛弃双亲委派加载链模式,使用线程上下文里的类加载器加载类。典型的例子有:通过线程上下文来加载第三方库jndi实现,而不依赖于双亲委派。大部分java application服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。还有一些采用hot swap特性的框架,也使用了线程上下文类加载器,比如 seasar (full stack framework in japenese)。
网友评论