一、类的生命周期:从诞生到退场的 5 步旅程
类的 “一生” 要经历加载、连接、初始化、使用、卸载,其中连接是 “安检环节”,包含验证、准备、解析三步。特别注意:解析阶段像 “灵活的安检项”,不一定按顺序来,可在初始化后启动。
二、类加载过程:5 步搭建运行基础
- 加载:如同 “寻宝”,按路径找到 class 文件并导入 JVM。
- 验证:好比 “质检”,检查 class 文件是否符合 JVM 规范,杜绝 “不合格品”。
- 准备:给类的静态变量 “分配房间”(内存),并设好默认初始值。
- 解析:把常量池里的 “符号名片”(符号引用)换成 “实际地址”(直接引用),让 JVM 能精准找到资源。
- 初始化:为静态变量赋真实值、执行静态代码块,给类 “激活生命力”。
三、初始化顺序:严格的 “启动流程”
必须按以下顺序执行,像按步骤组装机器:
- 父类静态成员→父类静态代码块
- 子类静态成员→子类静态代码块
- 父类实例变量→父类非静态代码块→父类构造函数
- 子类实例变量→子类非静态代码块→子类构造函数
四、触发初始化:6 种 “启动信号”
出现以下情况,类会被 “唤醒” 初始化:
- 用new创建对象,好比 “召唤” 类的实例
- 访问 / 修改类 / 接口的静态变量,或调用静态方法
- 反射加载(如Class.forName),像 “远程唤醒”
- 初始化子类时,先 “唤醒” 父类(父类优先)
- 虚拟机启动时,启动类(含main方法)自动初始化
五、类加载器:类的 “专属搬运工”
类在 JVM 中的唯一性,由 “搬运工”(类加载器)和类本身共同决定,每个 “搬运工” 有独立 “仓库”(类名称空间)。主要分 4 类:
- 启动类加载器:搬运 Java 安装目录lib下的核心类库,是 “顶层搬运工”。
- 扩展类加载器:搬运lib\ext或系统变量指定路径的类库,负责 “扩展资源”。
- 应用程序类加载器:搬运ClassPath下的类,是默认 “搬运工”,可直接调用。
- 自定义类加载器:应对特殊场景(如加载加密 class),按需定制 “专属搬运工”。
六、类加载机制:3 条 “工作规则”
- 全盘负责:“搬运工” 加载一个类时,顺带搬运该类依赖的其他类,除非指定其他 “搬运工”。
- 父类委托:“搬运工” 收到任务,先交给父 “搬运工” 尝试,父类办不到才自己上,避免重复劳动。
- 缓存机制:加载过的类会存入 “缓存仓库”,下次用先查缓存,没找到再重新加载 —— 这就是修改 Class 后需重启 JVM 的原因。
七、双亲委派:“层层上报” 的安全机制
“搬运工” 收到加载请求,先委托父 “搬运工”,依次向上到启动类加载器。只有父类 “找不到”,子类才自己加载。比如应用程序类加载器加载类时:
应用类加载器→扩展类加载器→启动类加载器(失败)→扩展类加载器(失败)→应用类加载器(加载),失败则抛ClassNotFoundException。
自定义类加载器时,建议重写findClass方法,别改loadClass,避免破坏这套 “安全规则”。
八、为何需要父类委托?2 大核心原因
- 避免重复加载:不同 “搬运工” 不会重复加载同一类,节省内存。
- 保障安全:核心类由顶层 “搬运工” 加载,防止恶意类篡改核心逻辑。