构造方法是对象创建时自动执行的初始化逻辑,无返回类型、名须与类同;编译器默认提供无参构造,但自定义任一构造后即消失;可重载不可继承,子类须用super()显式调用父类构造;框架反射等场景常依赖无参构造。

构造方法是什么:不是函数,是对象诞生时自动触发的初始化逻辑
Java里构造方法没有返回类型(连void都不能写),名字必须和类名完全一致。它不是普通方法,更不是“创建对象的函数”——new才是创建动作,构造方法只是new执行完内存分配后,立刻被调用来填充初始状态的那段代码。
- 如果你没写任何构造方法,编译器会悄悄加一个
public 类名() {},这就是默认无参构造 - 一旦你写了任意一个构造方法(哪怕是有参的),这个默认无参构造就自动消失
- 构造方法可以重载,但不能被继承,子类也不能直接调用父类的构造方法(得用
super())
无参构造 vs 有参构造:重载规则和调用时机完全不同
重载只看参数列表,所以Person()和Person(String name)、Person(String name, int age)天然就是重载关系。但它们的触发时机取决于你用new时传了什么。
-
new Person()→ 调用无参构造 -
new Person("Alice")→ 调用Person(String) -
new Person()在没有显式无参构造时会编译失败,不是运行时报错
常见错误现象:Error: constructor Person in class Person cannot be applied to given types
原因往往是:你写了有参构造,又忘了补无参构造,而某处代码(比如某些框架反射实例化)硬要调new Person()。
子类中如何调用父类构造:不写super(...)就默认走super(),但前提是父类有无参构造
子类构造方法第一行,要么是this(...)(调本类其他构造),要么是super(...)(调父类构造)。啥都不写?编译器自动插入super()。
- 父类只有
Person(String),子类构造又没显式写super("xxx")→ 编译失败 - 父类没无参构造,子类想用
super(name),但参数类型或个数对不上 → 编译失败 -
super(...)必须是第一行;放在第二行会报call to super must be first statement
性能影响很小,但逻辑链很关键:对象初始化顺序是「父类静态块 → 子类静态块 → 父类实例块 → 父类构造 → 子类实例块 → 子类构造」,跳过super()等于跳过父类初始化,字段可能为null或0。
立即学习“Java免费学习笔记(深入)”;
什么时候必须自己写无参构造:框架、序列化、测试Mock都依赖它
Spring Bean、MyBatis ResultMap、Jackson反序列化、JUnit的@Mock等,多数靠反射调Class.newInstance()或Constructor.newInstance(),而这些 API 默认找无参构造。
- JPA实体类如果只有
User(String name, String email),Hibernate启动直接抛InstantiationException - Lombok的
@Data默认不生成无参构造,得加@NoArgsConstructor - 单元测试里用
Mockito.mock(User.class),如果User没无参构造,mock会失败
这不是设计偏好,是现实约束:很多工具链没能力推断你想要哪个有参构造,也不该替你决定参数值。
有些场景下,你确实需要禁止无参构造(比如强制校验必填字段),那就得配合构建器模式或private无参构造+静态工厂,但得清楚代价:放弃一部分框架兼容性。










