java类加载知识点
所属分类 java
浏览量 1421
类装载三个阶段
载入 (Load)
载入二进制流字节流,解释成运行时数据结构,生成一个Class对象
链接 (Resolve)
将载入的数据结构里的符号引用表,解析成直接引用。
中间如果遇到引用的类还没被加载,触发该类的加载。
JVM可能在运行某个函数实际使用到该引用时才发生链接,也可能在类加载时就解析全部引用。
初始化 (Initniazle)
初始化静态变量,并执行静态初始化语句。
类装载的时机
ClassLoader.loadClass()
链接时触发装载
Class.forName() 等 反射调用
new 创建对象
初始化子类时,触发父类加载
访问类的静态变量或静态方法( static final 常量除外,在常量池里)
ClassLoader.loadClass() 与 Class.forName()
ClassLoader.loadClass(String name, boolean resolve)
resolve默认为false,只执行类装载的第一个阶段
Class.forName(String name, boolean initialize, ClassLoader loader)
initialize默认为true,执行到类装载的第三个阶段
ClassNotFoundException 和 NoClassDefFoundError
ClassLoader.loadClass() 与 Class.forName() 找不到类二进制流时抛出ClassNotFoundException
链接阶段失败,找不到引用的类时抛出NoClassDefFoundError
ClassLoader双亲委派机制
ClassLoader.loadClass() 标准流程
findLoadedClass() 查看类是否已加载
如果不存在,则调用parent loader的loadClass()
如果不存在,调用findClass() 在当前ClassLoader的ClassPath里加载类
先从parent loader开始查找,找不到了才用自己加载
避免重复加载
安全,避免子类乱加载
OSGI或SPI或热替换方案 破坏双亲委托 先自己加载
findClass() 读取字节流
defineClass() 根据传入的字节流,返回 Class对象
JDK6 loadClass 使用 synchronized
JDK7 以Class Name为Key的 parallelLockMap 并行加载不同Class的能力
System ClassLoader 与 Thread Context Classloader
默认的三层ClassLoader机制
Bootstrap 加载jdk的lib目录
Extension 加载jdk的lib/ext目录
Application 加载 classpath
ClassLoader.getSystemClassLoader()
sun.misc.Launcher$ApplicationClassLoader
类A里加载类B,默认使用 类A的Loader
特殊场景 JDBC 驱动加载
在父 ClassLoader(JDBC 属于 JDK一部分)里反射创建 jdbc driver 实现类
Thread Context Class Loader
Java Agent
JDK5开始,增加 JVM 参数 -javaagent ,在装载Class时对类进行动态的修改
ClassFileTransformer s_transformer = new ClassPreProcessorAgentAdapter();
public static void premain(String options, Instrumentation instrumentation) {
instrumentation.addTransformer(s_transformer);
}
ClassFileTransformer
defineClass
修改二进制字节流
Jar包的预加载
加载某个Class 所在的Jar里的全部的Class
URL jarUrl = ClassXXX.getProtectionDomain().getCodeSource().getLocation();
JarFile jarfile = new JarFile(jarUrl.getPath());
Enumeration entries = jarfile.entries();
遍历JarEntry,获取.class文件,按类名装载
类加载器中findClass与loadClass的区别
URLClassLoader简介
自定义类加载器例子
上一篇
下一篇
httpclient post json数据
jmx信息获取
JMX之Jolokia使用
java代码获取所有jvm进程
ETF投资指南
银华日利(511880) vs 华宝添益(511990)