抽象类虽不能实例化,但必须有构造器,因其承担子类初始化链的强制入口职责:校验参数、设默认值、初始化final字段,并与final结合保障不可变性。

抽象类不能 new,但必须有构造器——这不是矛盾,而是分工明确:构造器不负责“造出自己”,只负责“帮子类把基础打牢”。
构造器是子类初始化链的强制入口
Java 规定,每个子类构造器第一行必须调用父类构造器(显式 super() 或隐式无参 super())。即使父类是抽象的,这条规则照常生效。JVM 在创建子类对象时,会严格按继承链从上到下执行构造逻辑,抽象类的构造器就在这条链中被触发。
- 若抽象类只提供带参构造(如 Animal(String name)),子类构造器必须显式写 super(name),否则编译失败
- 若抽象类没写任何构造器,编译器自动补一个无参构造,子类可不写 super(),系统隐式调用
- 这个机制把初始化责任前移到抽象层,避免子类各自随意初始化导致状态不一致
构造器承担参数化、校验型初始化任务
静态块只能执行一次,实例块无法接收参数,只有构造器能结合运行时传入的值完成个性化初始化。它适合做三类关键事:
- 校验必填项:比如检查 name != null、age > 0
- 设默认或规范化值:如 status = "INIT"、url = url.trim().toLowerCase()
- 初始化 final 字段:所有 protected final String id 类字段,必须且只能在构造器中赋值
构造器与不可变设计绑定,形成初始化契约
用 final + protected 构造器组合,能强制子类在创建对象时就提供合规配置,并杜绝后续篡改:
立即学习“Java免费学习笔记(深入)”;
- 子类无法绕过构造器——super(...) 是语法硬性要求
- final 字段一旦在构造器中赋值,就不可再修改,保障核心属性的完整性
- 所有子类共享同一套初始化语义,便于统一日志记录、监控埋点和单元测试
注意避开构造器中的常见陷阱
抽象类构造器虽强大,但使用时有明确边界:
- 禁止调用抽象方法:子类对象尚未构造完成,此时调用抽象方法可能访问未初始化的字段,引发空指针或逻辑错误
- 字段建议声明为 protected,而非 private,否则子类无法直接访问继承来的状态
- 不要在构造器中启动线程、打开连接或执行耗时操作,这会拖慢对象创建,也违背构造器“轻量初始化”的本意


















