1. Java程序执行时遵循以下顺序
1.1. 加载:将类的.class文件中的二进制数据装载到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Object对象,用来封装类在方法区的数据结构
1.1.1. 加载.class方式:
1.1.1.1. 从本地系统中加载
1.1.1.2. 通过网络下载.class
1.1.1.3. 从zip、jar等文件中加载.class
1.1.1.4. 从数据库中提取.class
1.1.1.5. 将Java源文件动态编译成.class
1.2. 连接:
1.2.1. 验证:确保被加载的类的正确性
1.2.2. 准备:为类的静态变量分配内存,并将其初始化为默认值
1.2.3. 解析:把类中的符号引用转换为直接引用
1.3. 初始化:为类的静态变量赋予正确的初始值
Notice : 准备的初始化为默认值与初始化赋予正确的初始值不是一个意思
public class Student { private static int a = 1; }
准备阶段,a的默认值是0,初始化的阶段a才等于3
上面这个过程等同于以下代码:
public class Student { private static int a; static{ a = 3; } }
只有静态变量在准备阶段才被初始化,那么类在什么时候初始化呢?
public class Handsome{ public int a =1; public static void sayHi(){} } public class Child extends Handsome{
private static int b = 2; public static void main(String [] args){
Child.b = 3;
} }
2. Java程序对类的使用方式分为两种:
1.1. 主动使用(6种)
1.1.1:创建类的实例 --> new Handsome()
1.1.2:访问某个类或接口的静态变量,或者对该静态变量赋值 --> Handome.a = 2
1.1.3:调用类的静态方法 --> Handsome.sayHi()
1.1.4:反射 --> Class.forName("com.fajun.Handsome")
1.1.5:初始化一个类的子类 --> Child.b = 3
1.1.6:Java虚拟机启动时被标明为启动类的类 --> 含main方法启动的类
1.2. 被动使用: 除开上面6种的其他方式,都不会导致类被初始化
3. 每个类或接口被Java程序“首次主动使用”时才初始化