如何从 Java 中的另一个构造函数调用构造函数:深入解析

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何在 Java 中从一个构造函数调用另一个构造函数:将改变您代码的隐藏细节



您是否曾经编写过一个包含 5-6 个构造函数的 Java 类,并感觉自己被代码重复所淹没?或者,相反,您是否看过别人的代码,其中出现神秘的 this(name, 0, true),并想知道:“这是什么魔法?”



“How do I call one constructor from another in Java?” 这个问题是 Stack Overflow 上最热门的问题之一(数千次浏览和数百个回答)。这并非偶然。看似简单的操作——调用构造函数——却隐藏着许多影响性能、可读性甚至程序正确性的细微差别。



在本文中,我们不仅会展示语法。我们将深入 JVM 内部,分析编译器如何处理此类调用,并提供对新手和经验丰富的开发人员都有用的实用建议。



为什么需要从一个构造函数调用另一个构造函数?重复问题



假设您正在编写一个 User 类,它既有必填字段(姓名、电子邮件),也有可选字段(年龄、电话)。您希望为 API 的用户提供灵活性:使用最少的数据集或所有详细信息创建对象。



糟糕的方法(不调用构造函数):

public class User {    private String name;    private String email;    private int age;    private String phone;

public User(String name, String email) { this.name = name; this.email = email; this.age = 0; // 默认值 this.phone = null; // 默认值 }

public User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; this.phone = null; // 再次重复 }

public User(String name, String email, int age, String phone) { this.name = name; this.email = email; this.age = age; this.phone = phone; }}


这里我们三次赋值了 name 和 email。添加新字段时,必须修改所有构造函数。这违反了 DRY(Don't Repeat Yourself)原则,并增加了出错的风险。



好的方法(通过 this() 调用构造函数):

public class User {    private String name;    private String email;    private int age;    private String phone;

public User(String name, String email) { this(name, email, 0, null); // 委托给最“完整”的构造函数 }

public User(String name, String email, int age) { this(name, email, age, null); // 再次委托 }

public User(String name, String email, int age, String phone) { this.name = name; this.email = email; this.age = age; this.phone = phone; }}


现在所有初始化逻辑都在一个构造函数中。其他构造函数只是将工作委托给它,传递默认值。这简洁、易于维护,并且忘记字段的可能性更小。



调用构造函数的语法:this() 和 super()



在 Java 中,有两个用于调用构造函数的关键字:

  • this(参数) — 调用同一类的另一个构造函数。
  • super(参数) — 调用父类的构造函数。


最重要的规则: this() 或 super() 调用必须是构造函数中的 第一条语句。为什么?稍后会解释。



继承示例:

class Animal {    private String species;

public Animal(String species) { this.species = species; System.out.println("Animal constructor: " + speci

博客

书籍推荐