核心概念:把Java类加载想象成游乐园的运营过程:
类加载阶段 = 开园准备(一次性)
对象创建阶段 = 游客入园(每次new触发)
方法调用阶段 = 游玩过程(自由调用)
🗺️ 整体加载流程图
🌟 一、类加载阶段(游乐园开园准备)
当JVM首次使用类时(比如第一次new AmusementPark()
或访问静态成员),触发一次性加载:
代码示例:
public class AmusementPark {
// 1. 静态常量 - 入园须知牌 🪧 (编译期确定)
public static final String OPEN_TIME = "09:00";
// 2. 静态变量 - 游客计数器 👥 (默认0 → 显式赋值)
public static int totalVisitors = 0;
// 3. 静态块 - 开园仪式 🎪 (按代码顺序执行)
static {
System.out.println("🎪 静态块:游乐园开园!");
System.out.println("⏰ 开放时间:" + OPEN_TIME);
}
}
执行顺序:
静态常量
OPEN_TIME
(像入园规则牌,立好就不变)静态变量
totalVisitors
(像游客计数器,开园时归零)静态块(像开园仪式,只举行一次)
💡 场景:静态块适合初始化全局配置(如数据库连接池)
👨👩👧 二、对象创建阶段(游客入园)
每次new
就像新游客入园,触发完整初始化流程:
代码示例:
public class AmusementPark {
// 4. 实例变量 - 游客手环 💫 (每个游客独有)
private String visitorBand;
// 5. 实例块 - 安检通道 🛂 (在构造器之前执行)
{
System.out.println("🛂 实例块:游客通过安检");
visitorBand = "VIP-" + System.currentTimeMillis(); // 生成唯一手环
}
// 6. 构造器 - 入园欢迎 🎉 (最终初始化)
public AmusementPark(String name) {
System.out.println("🎉 构造器:欢迎" + name + "!");
totalVisitors++; // 更新静态计数器
}
}
关键点:
实例块会在每个构造器中隐式插入(类似安检通道必经之路)
构造器可重载,但实例块代码会统一执行
💡 场景:实例块适合对象公共初始化(如日志ID生成)
🎢 三、方法调用阶段(游玩过程)
对象创建后,可随时调用方法:
示例方法:
// 7. 实例方法 - 游玩项目 🎢
public void playGame(String gameName) {
System.out.println(visitorBand + "正在玩【" + gameName + "】");
}
// 8. 静态方法 - 闭园统计 📊
public static void closePark() {
System.out.println("🔚 闭园!今日游客总数:" + totalVisitors);
}
规则:
实例方法必须通过对象调用(需先有"游客手环")
静态方法通过类名调用(直接找"园区管理处")
🎯 四、完整场景演示
public static void main(String[] args) {
System.out.println("==== 游乐园启动 ====");
// 首次触发类加载
AmusementPark visitor1 = new AmusementPark("小明");
visitor1.playGame("过山车");
AmusementPark visitor2 = new AmusementPark("小红");
visitor2.playGame("旋转木马");
AmusementPark.closePark();
}
输出结果:
==== 游乐园启动 ====
🎪 静态块:游乐园开园!
⏰ 开放时间:09:00
🛂 实例块:游客通过安检
🎉 构造器:欢迎小明!
🛂 实例块:游客通过安检
🎉 构造器:欢迎小红!
VIP-1623912000正在玩【过山车】
VIP-1623912005正在玩【旋转木马】
🔚 闭园!今日游客总数:2
执行时序图:
📚 五、关键规则总结表
🧩 六、继承场景加餐(亲子游客通道)
父子类初始化顺序:
示例:
class Parent {
static { System.out.println("👨 父类静态块"); }
{ System.out.println("👨 父类实例块"); }
Parent() { System.out.println("👨 父类构造器"); }
}
class Child extends Parent {
static { System.out.println("👶 子类静态块"); }
{ System.out.println("👶 子类实例块"); }
Child() { System.out.println("👶 子类构造器"); }
}
// 输出顺序:
// 👨 父类静态块 → 👶 子类静态块 →
// 👨 父类实例块 → 👨 父类构造器 →
// 👶 子类实例块 → 👶 子类构造器
🚀 七、实战应用场景
静态块初始化全局配置(开园时准备物资):
public class ConfigLoader {
public static final String API_KEY;
static {
// 从配置文件加载
API_KEY = loadKeyFromFile();
}
}
实例块统一验证(游客安检):
public class Rider {
private int height;
{
if (height < 120) {
throw new RuntimeException("❌ 身高不足120cm不能游玩");
}
}
}
静态常量定义配置(园区固定规则):
public class ParkRules {
public static final int MAX_AGE = 70;
public static final int MIN_HEIGHT = 110;
}
通过游乐园的完整生命周期,配合可视化流程图,Java类的加载顺序变得像游玩路线一样清晰!记住三个关键阶段:
静态准备 = 开园仪式(一次性)
对象创建 = 游客入园(按票入场)
方法调用 = 自由游玩(随时进行)
现在,你已经掌握了JVM加载的核心秘密!🎉
评论区