Java命令执行代码流程
当用Java命令去运行一个Class文件时,执行流程如下:
loadClass类加载过程由一下几步组成:
类被加载到方法区中,主要包含:
-
运行时常量池
-
类型信息
-
字段信息
-
方法信息
-
类加载的引用
加载这个类的ClassLoader实例的引用
-
对应Class实例的引用
对应堆中Class类型的对象实例,比如com.xxx.Class.class,作为访问方法区中类定义的入口。
类加载器
Java里面有一下几种类加载器:
- 引导类加载器:负责加载支持JVM运行的jre的lib目录下的核心jar包,比如rt.jar;
- 扩展类加载器:负责加载支持JVM运行的jre的lib目录下ext扩展目录的jar包;
- 应用程序加载器:负责加载ClassPath路径下的包,主要是加载自己写的类;
- 自定义类加载器:负责加载用户自定义目录下的jar或者class文件;
类加载器初始化过程
在Launcher的构造方法中,创建了两个类加载器,分别是ExtClassLoader扩展类加载器,AppClassLoader应用类加载器。
默认使用Launcher#getClassLoader()返回类加载器AppClassLoader加载应用程序。
自定义类加载器
只需要继承java.lang.ClassLoader类,重写其findClass()即可。
双亲委派机制
简单说就是在加载类的时候,先由父类加载器加载,如果父类加载的加载路径下找不到目标Class,则在自己的类加载路径下查找Class,并加载类。
为什么要有双亲委派机制呢?
- 安全机制:防止Java核心API被修改;
- 避免类重复加载:当父类加载器已经加载该类时,子类加载器就没必要在加载了,保证被加载类的唯一性;
全盘委托机制
指的是当一个Class被ClassLoader加载时,这个Class所依赖的类都将由这个ClassLoader加载,除非显式的使用另外一个ClassLoader。
打破双亲委派机制
只需要继承ClassLoader,重写findClass()和loadClass()方法
protected Class<