前言:大家都知道,在我们启动Java程序的时候包括以下几步:
编写:是指在 Java 开发环境中进行程序代码的输入,最终形成后缀名为 .java 的 Java 源文件。
编译:是指使用 Java 编译器对源文件调用javac来进行错误排査的过程,编译后将生成后缀名为 .class 的字节码文件
运行:是指使用 Java 解释器将字节码文件翻译成机器代码,执行并显示结果。
类加载的全过程:
1)加载:将class文件字节码(可以是文件里,也可以是网络中来的,本质就是一个字节数组)类容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的Java.lang.class对象(即生成一个反射对象,这个反射对象可以指向方法区中的这些类的数据,如果外部程序想要访问类的信息,只能通过这个class对象来访问),作为方法区类数据的访问入口. ps:此过程需要类加载器的参与.
通过类的加载:在堆中的方法区里多了类的信息(二进制数据),在堆里面多了class对象.
2)链接[验证,准备,解析]:将Java类的二进制代码合并到JVM的运行状态之中的过程
*验证:确保加载的信息符合JVM规范,没有安全方面的问题.
*准备:正式为类变量(static变量)分配内存并设置变量初始值的阶段,这些内存都将在方法区中进行分配
*解析:虚拟机内常量池中的符号引用替换为直接引用的过程.
3)初始化
a):初始化阶段是执行类构造器()方法的过程.类构造器()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的.
b)当初始化一个类的时候,如果发现其父类还没有被初始化,则先初始化其父类.
c)虚拟机会保证一个类的()方法在多线程中被正确加锁和同步.
d)当访问一个Java类的静态域时,只有真正声明这个域的类才会被初始化.
/**
* @author TR
* @date 2020/5/30 - 下午 5:31
*/
public class Demo2 {
public static void main(String[] args) {
A q = new A();
System.out.println(q.a);
}
}
class A {
public static int a = 100;
static {
System.out.println("静态初始化类A");
a = 200;
}
public A() {
System.out.println("创建A类的对象");
}
}
结果:
静态初始化类A
创建A类的对象
200
(部分资源来源于千锋教育)