类加载分析–实战部分
1、首先编写一个类供我们调用
class A {
static {
System.out.println("A类静态代码块初始化!");
m = 300;
}
static int m = 100;
public A() {
System.out.println("A类无参构造函数初始化");
}
}
2、调用我们这个类
public class ClassLoadTest {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
输出结果如下:
A类静态代码块初始化!
A类无参构造函数初始化
100
3、分析为啥会输出这样的结果?
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次
构造代码块:类中直接用{}定义,每一次创建对象时执行。
执行顺序优先级:静态块,main(),构造块,构造方法。
流程
加载:
首先类的信息会被放置到方法区(特殊的堆)当中。
类的信息:静态变量、静态方法、常量池、代码...其它的等等。
然后生成代表这个类的java.lang.Class对象会放到堆内存中。
链接:
验证阶段--这个就不赘述了。
准备阶段:主要是为类变量(注意,不是实例变量)分配内存,并且赋予初值。
解析阶段:将常量池内的符号引用替换为直接引用的过程。
初始化:
上述过程中的m的值为什么是100不是300。
编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。
这个合并关键字很重要,这个赋值过程和这个m赋值过程的自然顺序有关,静态代码块在定义这个静态变量上面以下面的初始化值为准,静态代码块在这个在定义这个静态变量下面,以下面静态代码块中的赋值的为准(进行覆盖)
程序的调用都是进行压栈的过程(先进后出)
这些执行的过程都会在栈中进行执行,然后Main()方法进行压栈的动作进行执行代码
评论区