在 Java 中,this()
和 super()
不能同时出现在同一个构造器中,因为它们都必须作为构造器的第一条语句,而一个构造器的第一条语句只能有一个。以下是详细解释和示例:
⚠️ 核心规则
- 只能二选一:
每个构造器的第一条语句必须是this()
(调用本类其他构造器)或super()
(调用父类构造器),不能同时存在。 - 默认的
super()
:
如果构造器中既没有显式写this()
也没有super()
,编译器会默认插入super()
(调用父类的无参构造器)。
📝 正确示例
class Animal {
public Animal(String name) {
System.out.println("Animal构造器: " + name);
}
}
class Dog extends Animal {
// 主构造器(显式调用父类构造器)
public Dog(String name) {
super(name); // 必须放在第一行
System.out.println("Dog构造器");
}
// 无参构造器 → 调用本类的有参构造器
public Dog() {
this("默认狗名"); // 调用本类的 Dog(String name)
}
}
❌ 错误示例
class Cat extends Animal {
public Cat() {
super("猫"); // 正确:调用父类构造器
this("小黑"); // 错误!this() 必须在第一行,且不能与 super() 共存
}
public Cat(String name) {
// 错误!既没有 this() 也没有 super(),编译器会默认插入 super(),
// 但父类 Animal 没有无参构造器,导致编译错误!
}
}
🔍 关键点总结
初始化顺序:
- 如果构造器中用
this()
调用本类其他构造器,被调用的构造器最终必须调用super()
(直接或间接)。 - 父类构造器的逻辑总是先于子类构造器执行。
- 如果构造器中用
父类无默认构造器的陷阱:
- 如果父类没有无参构造器,子类构造器必须显式调用有参的
super(参数)
,否则会编译错误。
- 如果父类没有无参构造器,子类构造器必须显式调用有参的
代码复用:
- 通过
this()
集中初始化逻辑,避免重复代码。 - 通过
super()
确保父类正确初始化。
- 通过
🌰 进阶示例
class Parent {
public Parent(int x) {
System.out.println("Parent构造器: x=" + x);
}
}
class Child extends Parent {
public Child() {
this(10); // 调用本类的 Child(int x)
}
public Child(int x) {
super(x); // 调用父类的 Parent(int x)
System.out.println("Child构造器: x=" + x);
}
}
- 执行
new Child()
的输出:Parent构造器: x=10 Child构造器: x=10
⚡ 总结
this()
和super()
是互斥的,只能选其一作为构造器的第一条语句。- 合理使用
this()
和super()
可以优化代码结构,确保对象初始化的正确性。