首页  

java类加载知识点     所属分类 java 浏览量 194
类装载三个阶段

载入 (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文件,按类名装载

上一篇     下一篇
httpclient post json数据

jmx信息获取

JMX之Jolokia使用

java代码获取所有jvm进程

ETF投资指南

银华日利(511880) vs 华宝添益(511990)