在Java中,初始化块(init块)是特殊的代码块,在创建类的对象实例时执行,但在调用构造函数之前。存在两种类型:
public class Example { static { System.out.println("静态块"); } { System.out.println("实例块"); } public Example() { System.out.println("构造函数"); } }
创建新对象时将输出:
静态块
实例块
构造函数
使用初始化块是有意义的,当需要所有构造函数的通用逻辑,或者复杂的初始化不适合声明变量时。但通常优先选择构造函数。
问题: 在创建对象时,字段、静态块、实例块和构造函数的初始化顺序是什么?
答案:
故事
在一个大型项目中,初始化出现了问题:一位开发人员将常见逻辑从构造函数移到初始化块,而没有考虑调用顺序。结果是一些字段在逻辑执行前没有被正确初始化,导致在创建对象时出现NullPointerException。
故事
在一个抽象类中重复使用大型初始化块,导致其他类在继承时没有正确重写初始化顺序。这造成了继承时的意外行为和与初始化块和构造函数调用顺序相关的错误。
故事
开发人员认为静态字段可以在每次新建对象时重新初始化,并在静态块中添加了资源清理逻辑。这导致资源仅在类加载时清理一次,而后续的内存管理则“崩溃”。因为静态块只执行一次,这导致了内存泄漏和资源管理不当。