Java 后端面试题库 / 全部题解免费阅读理解原理,有条理地回答

哪些情况会触发类加载?怎样区分初始化?

先说出你的答案

定义边界、关键机制、一个反例;P8题再补容量、失败与验证。

查看完整题解

参考回答

直接回答

加载是把类的定义引入运行环境,连接包含验证、准备和解析,初始化才会执行类初始化逻辑。JVM 可以按需要安排加载与连接,因此面试中常背的 new、调用静态方法等“主动使用”,更准确地说主要是在讨论初始化触发条件,不能把三个阶段当成同一件事。

讲清原理

首次主动创建实例、调用类声明的静态方法、使用类声明的非编译期常量静态字段等,会涉及相应类的初始化;反射也可能触发,取决于具体 API。初始化类时还需要先初始化相应父类,接口的规则又有区别。

读取已经内联的编译期常量,不要求初始化声明它的类。创建某类型的数组,也不等于初始化其元素类型。Class.forName 的常用重载会初始化,而带 false 的重载可以只要求加载而不因该调用初始化。

加载、连接、初始化是不同阶段,主动使用可能触发初始化
加载、连接、初始化是不同阶段,主动使用可能触发初始化

例子与易错点

static class InitTarget {
    static final int CONSTANT = 7;
    static { System.out.println("初始化"); }
}
System.out.println(InitTarget.CONSTANT); // 7,不因这次读取初始化
Class.forName("Snippet$InitTarget"); // 随后才打印 初始化

这里类按示例包装为 Snippet 的静态嵌套类。初始化触发时要看字段实际声明者;通过子类名访问父类静态字段,并不因此要求初始化子类。

相关题:第 28 题、第 36 题、第 68 题。

这道题,你掌握得怎么样?

掌握程度由你主动标记,阅读和收藏不会自动改变状态。