只能在构造器第一行调用this()且仅一次,用于跳转到匹配参数的另一构造器,执行完后才继续当前构造器剩余代码;不可与super()共存,不支持自动类型转换,不能在静态或普通方法中调用。

构造器里怎么用 this() 调另一个构造器
只能在构造器第一行调用 this(),且只能调一次。这不是普通方法调用,而是编译器强制的“构造链起点”。你写 this("a", 123),JVM 就会跳转到匹配参数的另一个构造器执行,当前构造器剩下的代码要等那个构造器完全返回后才继续(实际是串行执行,不是嵌套)。
常见错误现象:Constructor call must be the first statement in a constructor —— 多半是你在 this() 前写了变量声明、if 或日志;或者同一构造器里写了两次 this() 或 super()。
-
this()和super()互斥:一个构造器里不能同时出现 - 参数必须严格匹配重载构造器签名,不支持自动装箱或隐式类型提升(比如传
int却想匹配Integer参数的构造器,会报错) - 不能在静态上下文、普通方法、或
try块里调用this()
this() 调用失败的典型编译错误
最常遇到的是 Cannot resolve constructor 或 call to this() must be first statement。前者往往因为参数类型/数量没对上,后者基本就是位置错了。
例如这个类:
立即学习“Java免费学习笔记(深入)”;
class Person {
Person(String name) { /* ... */ }
Person(String name, int age) {
System.out.println("before this");
this(name); // ❌ 编译错误:not first statement
}
}改成这样才合法:
Person(String name, int age) {
this(name); // ✅ 必须第一行
System.out.println("after this"); // 这行在 Person(String) 执行完才跑
}为什么不能在 this() 后初始化 final 字段
因为 final 字段必须在构造器结束前明确赋值,而 this() 调用的目标构造器可能已经赋过值了。如果你在当前构造器里再赋一次,编译器会报 variable might already have been assigned。
- 所有
final字段的初始化,应该集中放在被调用的那个“主构造器”里(通常是参数最多的那个) - 如果不同构造器需要给
final字段设不同默认值,得靠参数传递进去,而不是在各自构造器里重复赋值 - 字段初始化块(
{ ... })会在this()或super()调用之后、构造器剩余代码之前执行,但它不能绕过final的单次赋值检查
替代方案:什么时候该放弃 this() 改用工厂方法
当构造逻辑开始分支复杂(比如要根据参数做条件判断、读配置、抛异常),硬塞进构造器链反而会让代码难读、难测、难维护。
比如这些场景更适合用静态工厂方法:
- 需要校验参数合法性后再决定调哪个构造路径(
this()不允许if) - 要复用已有对象(如从缓存取、用对象池),而非每次都 new
- 构造过程可能抛受检异常,而构造器声明不能加
throws(除非全改成运行时异常)
这时候写个 public static Person fromNameAndAge(String name, int age),比堆砌 4 层 this() 调用更直白、更可控。
构造器链看着简洁,但一碰上真实业务逻辑里的分支、IO、异常,就容易变成黑盒。能不用 this() 就不用,不是语法限制,是可维护性问题。


















