加载:
1.通过一个类的全限定名获取该类的二进制文件。
2.将这个字节流代表的静态存储结构转化成方法区的运行时的数据jiegou
3.在内存中生成一个代表这个类的jvava.lang.class对象,作为方法区的这个类的各种数据的访问入口。
第二阶段:链接
1 验证
2.准备
为类的变量分配内存并且设置该类的变量的默认初始值 0值
注意:这里不包括final修饰的static ,因为final在编译的时候就会分配,准备阶段就会显示地初始化。(常量在编译的时候就会初始化值)
这里也不会为实例比那里分配初始化,类变量会分配在方法区,而实例变量会随着对象一起分配到java堆。
3.解析
字节码文件的开始:咖啡baby
第三个过程:
private static int a=10;
public static void main(String[] args) {
System.out.println(a);
}
像这样一个方法,首先,在准备阶段,会对这个类的成员变量进行一个0值初始化。接着在初始化的时候,会对这个类进行一个赋值a=10。
private static int a=10;
static {
a=50;
}
public static void main(String[] args) {
System.out.println(a);
}
在准备阶段,进行0值初始化。在初始化的时候,static是顺序执行的,先将10赋值给a,接着20覆盖了10.
具体的过程,我们可以通过反编译字节码文件,清楚地看出来。
第二个点,我们都知道,一个类都有一个默认的构造方法。真正的原因是在初始化的时候,会默认生成一个init的这样一个构造方法,这个构造方法,就是我们说的默认构造方法。
初始化:
jCLasslib插件