抽象类构造方法为子类初始化提供统一入口,执行字段赋值、参数校验等;子类必须调用super()确保继承链字段正确初始化,并封装共用逻辑;避免在构造中调用抽象方法以防NPE。

抽象类的构造方法不用于创建对象,而是为子类对象的初始化提供统一入口。当子类调用 super()(显式或隐式)时,抽象父类的构造逻辑就被执行,完成字段赋值、参数校验、资源准备等关键操作。
确保继承链中字段被正确初始化
抽象类常定义 protected 字段(如 name、id、timeoutMs),这些字段必须在子类对象“可用”前就具备有效值:
- 只有构造方法能接收参数并完成个性化赋值,比如
super("user", 3000) - 静态块只执行一次,无法响应每次 new 的不同参数
- 实例初始化块不接受参数,只能设固定默认值,灵活性不足
- 若字段是 final,必须在构造方法中赋值,否则编译报错
强制子类参与统一初始化流程
Java 规定:子类构造器第一行必须调用父类构造器。这条规则对抽象类同样适用:
- 如果抽象类只提供带参构造(如
Animal(String name)),子类构造器必须显式写super(name),否则编译失败 - 即使没写
super(),编译器也会自动插入对父类无参构造的调用——前提是抽象类提供了无参构造 - 这保证了从
Object到最深层子类,每层字段都按顺序初始化,状态一致
封装共用逻辑,避免子类重复实现
把校验、日志、资源加载等通用代码放在抽象类构造方法里,子类只需传参,无需关心细节:
立即学习“Java免费学习笔记(深入)”;
- 例如检查
name非空、timeoutMs> 0,抛出明确异常 - 初始化
Logger时使用getClass(),自动适配子类真实类型 - 若改用 setter 或实例块初始化,可能因调用时机不当导致空指针或状态错乱
不建议在构造中调用抽象方法
虽然语法允许(JVM 会调用子类实现),但此时子类字段尚未初始化,对象处于部分构建状态:
- 比如抽象类实例块中调用
chew(),输出结果正确,但子类自己的构造体还没执行 - 容易引发 NPE 或逻辑错误,属于危险但合法的行为
- 应尽量避免,初始化阶段优先使用 final 字段 + 构造参数驱动


















