抽象类虽不可实例化,但其构造方法会在子类调用super()时执行,用于统一初始化protected final共用属性,并校验参数、规范化处理;需避免在构造器中调用abstract方法或依赖未初始化的子类字段。

抽象类不能直接创建实例,但它的构造方法会在子类实例化时自动执行——只要子类调用 super()(显式或隐式),JVM 就会运行父类(包括抽象类)的构造逻辑,完成对共用属性的统一初始化。
用 final + protected 字段锁定共用属性
把所有子类都需要、且不应被修改的属性声明为 protected final:
-
final强制字段必须在构造器中赋值,否则编译失败;子类无法在后续代码中重新赋值 -
protected保证子类可访问,又避免包外误用 - 常见共用属性包括:名称、超时时间、日志器、配置对象、唯一标识等
在抽象构造器里集中校验和赋值
所有子类创建对象时,都必须经过这个入口。这里适合做三件事:
- 参数合法性检查(如
name != null、timeoutMs > 0) - 规范化处理(如
name.trim()、url.toLowerCase()) - 一次性完成
final字段赋值,以及共享资源初始化(如LoggerFactory.getLogger(getClass()))
子类只需传参,不重复写初始化逻辑
子类构造器第一行必须是 super(...),参数由抽象父类决定:
立即学习“Java免费学习笔记(深入)”;
- 如果抽象类只提供带参构造,子类无法省略
super(),也绕不过校验 - 子类即使定义同名字段,也不会覆盖父类
final字段(字段不参与继承重写) - 所有子类实例的共用属性,都来自同一套初始化语义,便于统一维护和测试
注意避开构造器中的陷阱
抽象类构造器执行时,子类对象尚未完全构建:
- 禁止在构造器中调用
abstract方法——此时子类实现可能还未就绪,容易触发NullPointerException - 不要依赖子类字段的值(它们还未被子类构造器赋值)
- 共享资源如线程池、连接池,建议延迟初始化或通过工厂注入,而非在构造器中硬编码创建


















