this(...)必须位于构造方法首行,因其用于委托本类其他构造器初始化对象,而JVM要求父类必须先完成初始化,且this与super不能共存、只能选其一作为构造链起点。

这个限制本质上是 Java 编译器和 JVM 为保证对象初始化过程安全、可控而设定的强制规则:在当前构造方法中,this(...) 必须是第一句可执行代码,否则编译直接失败。
为什么必须放在首行?
因为 this(...) 的作用是委托另一个构造方法完成对象的初始化。JVM 要求:在子类构造方法真正开始执行前,父类必须已完成初始化(即 super() 已调用);而 this(...) 本质是“跳转”到本类另一个构造器,它内部仍会隐式或显式调用 super()。如果允许 this(...) 出现在中间,就可能出现字段被访问、方法被调用,但对象尚未完成任何构造器初始化的情况——此时字段还是默认值(如 null、0、false),极易引发错误。
它和 super() 共享同一套约束
this(...) 和 super(...) 不能共存;二者都只能出现一次,且必须是构造方法的第一条语句。这是因为:
- JVM 只允许一次“构造链起点”的选择:要么交给父类构造器(super),要么交给本类另一个构造器(this);
- 一旦选了 this(...),那个被调用的构造器会负责处理 super() —— 你不能再自己写 super(),否则就是重复初始化;
常见误解与反例
有人想先做点校验再委托,比如:
❌ 错误写法:public Person(String name) {<br> if (name == null) throw new IllegalArgumentException();<br> this(name, 0); // 编译错误:this() 必须在第一行<br>}
正确做法是把校验逻辑移到被委托的构造器里,或者用静态工厂方法预处理:
✅ 正确写法(校验后委托):public Person(String name) {<br> this(name, 0); // 首行<br>}<br>public Person(String name, int age) {<br> if (name == null) throw new IllegalArgumentException();<br> this.name = name;<br> this.age = age;<br>}
底层视角:字节码不允许绕过
Java 字节码中,每个构造方法的前几条指令必须是 invokespecial 调用 java/lang/Object.










