1、加载类文件
a、读取class文件,从jar包、war包、class文件、jsp文件等处都可以。
a.1、采用双亲委派机制加载类,由classLoader和其子类完成,支持自定义ClassLoader。
如下图,由下至上,当一个类加载器收到类加载任务,会先交给其父类加载器去完成,
因此最终加载任务都会传递到 顶层的启动类加载器,只有当父类加载器无法完成加载任务时,才会尝试执行加载任 务。
好处是比如加载位于rt.jar包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类 加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个Object对象。
bootstrap ClassLoader 启动类加载器 加载JAVA_HOME/lib下的jar包
extension ClassLoader 扩展类加载器 加载JAVA_HOME/lib/ext目录下的jar
application ClassLoader 应用程序类加载器,加载用户自己的class文件 jar包等
b、生成一个java.lang.Class对象,作为方法区的该类的变量入口。
2、连接
2.1、验证,验证class文件的字节流是不是符合jvm规范,避免jvm被破坏。
2.2、准备,为类的变量分配内存,并设置初始值,简单来说就是为变量分配空间,这里需注意:此时设置初始值并不是变量 的真实值。
比如:public
static
int
a =
123
;本阶段赋值是0而不是123
final修饰的属性除外,public
static final
int
a =
123
;会将a设置成ConstantValue属性,并赋真实值123.
2.3、解析,将常量池中的符号引用替换为直接引用。
3、初始化,本阶段是jvm给类中的变量赋值和执行static代码块。