触发时机
main方法,需要用到类的时候才加载(new等,申明变量不加载),如果类未加载则加载类。
加载流程
Launcher类获取类加载器,双亲委派机制,加载类。
1、类加载器
类加载器是单例模式,用两个判断和synchronize来保证单例。
/**
* create an ExtClassLoader. The ExtClassLoader is created
* within a context that limits which files it can read
*/
public static ExtClassLoader getExtClassLoader() throws IOException
{
if (instance == null) {
synchronized(ExtClassLoader.class) {
if (instance == null) {
instance = createExtClassLoader();
}
}
}
return instance;
}
3种类加载器:
BootstrapClassLoader。加载位于JRE的lib目录下的核心类库。
ExtClassLoader。加载位于JRE的lib目录下的ext扩展jar包。
AppClassLoader。加载我们自己写的项目ClassPath路径下的类包。
2、双亲委派
类加载器加载时,先向上委派,上面不行再走自己的。核心方法loadClass
原因:
沙箱安全:避免自己写的类覆盖核心java类
单一:避免重复加载类
打破双亲委派tomcat:
双亲委派缺点:
一个类只有一个版本,因为是根据名称获取。tomcat中不同web针对同一个类需要不同版本。
如何打破?自定义类加载器extend ClassLoader,复写findClass方法。
------------------------------------插播其他小知识----------------------------------
可执行jar包的入口是META-INFO/MANIFEST.MF的main-class。如果没有main-class,这这个可能不是个可执行的jar,是个插件或库。
------------------------------------回到正题----------------------------------
3、加载类
加载:把类放入方法区。磁盘中.class文件到内存中
验证:验证是class文件是否正确
准备:设置静态字段的内存大小
解析:符号引用变为直接引用(静态链接)
初始化:静态字段初始化值,执行静态代码块