public class Test { public static void main(String[] args){ } } /* 9.1 类加载过程简介 类加载过程分为三个比较大的阶段,分别是加载阶段、连接阶段和初始化阶段。 加载阶段:负责查找并加载类的二进制数据文件。 连接阶段: 验证:确保类文件的正确性,如class的版本、class文件的魔术因子 准备:为类的静态变量分配内存,并且为其初始默认值 解析:把类中的符号引用转换为直接引用 初始化阶段:为类的静态变量赋予正确的初始值(代码编写阶段给定的值) ——静态变量被赋值了两次,第一次在准备阶段,第二次在初始化阶段 并非每个类都会被初始化。当一个类首次使用的时候才会被初始化,在同一个运行包下, 一个Class只会被初始化一次 */ /* 9.2 类的主动使用和被动使用 每个类或者接口被Java程序首次主动使用时才会对其进行初始化 6中主动使用类的场景: 1.通过new关键字导致类的初始化 2.访问类的静态变量,包括读取和更新 3.访问类的静态方法 4.对某个类进行反射操作 Class.forName("com.wangwenjun.concurrent.chapter09.Simple"); 5.初始化子类会导致父类初始化 通过子类使用父类的静态变量只会导致父类的初始化,子类不会被初始化 6.启动类,也就是执行main函数所在的类 观察: 我看到作者提供的案例,都是通过一个静态语句块,来证实说这个类被初始化了,也就是 说静态语句块其实是在初始化阶段执行的。 被动使用,不会导致类的加载和初始化: 1.构造某个数组时 Simple[] simples = new Simple[10]; 这行代码实际上只是开辟了一段连续的地址空间4byte*10 2.引用类的静态常量不会导致类的初始化 public final static int MAX = 100; //不会导致初始化 public final static int RANDOM = new Random().nextInt(); //由于计算复杂,会导致初始化,加载和连接阶段无法进行结算,需要初始化赋予正确的值 */ /* 9.3.1 类的加载阶段 将二进制数据读取到内存之中,然后将字节流代表的静态存储结构转换为方法区中 运行时的数据结构,并且在对内存中生成一个该类的java.lang.Class对象, 作为访问方法区数据结构的入口。 9.3.2 类的连接阶段 验证:验证文件格式、元数据验证、字节码验证、符号引用验证 准备:通过所有验证,为类的静态变量分配内存,并设置初始值 解析:在常量池中寻找类、接口、字段、方法的符号引用、并将这些符号引用转换成直接引用 9.3.4 类的初始化阶段 在初始化阶段,所有的类变量被赋予正确的值。 */
《Java高并发编程详解》笔记