Java对象的初始化顺序如下静态成员→实例成员→结构器final字段必须在结构器结束前唯一赋值构造器中禁止可重写方法资源需要显式销毁。Java对象的初始化顺序必须明确字段、构造器、初始化块谁先后Java对象的初始化不是按照代码书写顺序执行的而是有严格的优先级。错误的顺序会导致字段null或者默认值特别是在依赖注入或子类重写时。静态变量和静态初始化块(按出现顺序)→ 只执行一次加载类时实例变量赋值和实例初始化块(按出现顺序)→ 每次new比构造器早执行时执行构造器体 → 最后所有字段都“初始化”了但可能不是预期值public class InitOrder { private String a initA(); // 第二步执行 { System.out.println(init block); } // 第三步执行(与上同行) public InitOrder() { System.out.println(ctor: a); // 第四步a 已是 hello但若 initA() 依靠未初始化的其他字段是危险的 } private String initA() { System.out.println(initA called); return hello; } }注意initA()在构造器之前如果它访问了子类尚未初始化的字段(如被子类重写)getVal()就会得到null或0——这是空指针的常见来源。final字段的初始化必须符合“唯一赋值”规则否则编译失败final字段不是“只读”而是“只赋值一次”。Java要求它在对象结构完成前(即结构结束前)明确赋值不能通过条件分支遗漏路径。可在声明处直接赋值private final String id UUID.randomUUID().toString();可赋值每个结构器(包括所有重载结构器)不在普通方法getter 或在初始化块中“补赋值”若使用if-else每个分支都必须给予分支final字段赋值否则编译报错variable xxx might not have been initializedpublic class FinalExample { private final int code; public FinalExample(boolean success) { if (success) { this.code 200; } else { this.code 500; // 必须有否则编译失败 } } // 以下写法非法 // public FinalExample() { } // 缺少对 code 的赋值 }避免在构造器中调用可重写的方法这是由JVM规范决定的当子类对象创建时父类构造器首先运行但子类字段尚未初始化this引用已经是子类型了。如果父类结构被调用protected或public该方法实际执行子类重写版——但子类字段仍为默认值。立即学习“Java免费学习笔记(深入)现象子类toString()返回null或0奇怪的值在日志中看到根本原因this指向子类实例但子类结构尚未运行字段尚未初始化修复方法将方法改为private或static或者用工厂的方法代替构造器逻辑class Parent { public Parent() { init(); // 危险这里调用的是 Child.init() } public void init() { System.out.println(Parent.init); } } class Child extends Parent { private String data ready; Override public void init() { System.out.println(Child.init: data); // 打印 Child.init: null } }对象生命周期管理应区分“创造”、“使用”和“销毁”三个阶段Java有GC但这并不意味着没有资源的释放。就像InputStream、Connection、线程池必须显式关闭或回收否则句柄泄漏、内存堆积或连接耗尽。创建:建议使用静态工厂(如LocalDateTime.now()或构造器模式避免构造器参数爆炸使用:避免在对象内部缓存外部状态(如ThreadLocal未清理、避免长生命周期对象持有短生命周期对象销毁实现AutoCloseable并用 try-with-resources慎用finalize()已弃用非堆资源(如MappedBytebufer)需要主动clean()特别注意Spring Bean 的PreDestroy当容器正常关闭时只触发过程kill -9或崩溃时不执行——关键清理逻辑应放在业务完成后的显式调用点。