杰瑞科技汇

Java构造函数中this到底该怎么用?

核心概念

this() 在 Java 中是一个特殊的构造函数调用,用于在同一个类的另一个构造函数中调用该类的另一个构造函数

Java构造函数中this到底该怎么用?-图1
(图片来源网络,侵删)

它的主要目的是为了代码复用保证初始化逻辑的集中性,避免在多个构造函数中编写重复的初始化代码。


为什么要使用 this()

想象一个场景,你有一个 Student 类,它有多个属性,name, age, school,你可能需要提供多个构造函数来满足不同的初始化需求:

  1. 只提供 nameage
  2. 提供所有信息:name, age, school

如果不使用 this(),你可能会这样写:

public class Student {
    private String name;
    private int age;
    private String school;
    // 构造函数1:只初始化 name 和 age
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        // school 默认为 null
    }
    // 构造函数2:初始化所有信息
    public Student(String name, int age, String school) {
        this.name = name; // 重复代码
        this.age = age;   // 重复代码
        this.school = school;
    }
}

可以看到,在第二个构造函数中,this.name = name;this.age = age; 的代码是重复的。Student 类有更多属性,这种重复会更加严重。

Java构造函数中this到底该怎么用?-图2
(图片来源网络,侵删)

使用 this() 可以优雅地解决这个问题。


this() 的语法和规则

语法:

this(参数列表);

关键规则:

  1. 必须位于构造函数的第一行:这是 Java 语言的硬性规定。this() 调用是构造函数执行的第一步,这确保了任何初始化代码都在父类构造器(如果有)和当前类的其他初始化逻辑之前执行。
  2. 用于构造函数链:一个构造函数可以通过 this() 调用同一个类中的另一个构造函数,形成一条“构造函数链”。
  3. 不能与 super() 同时使用:因为 this()super() (调用父类构造函数) 都必须放在构造函数的第一行,所以它们不能同时出现在同一个构造函数中,一个构造函数要么用 this() 调用同类构造器,要么用 super() 调用父类构造器,要么两者都不用(此时会隐式调用父类的无参构造器)。
  4. 不能形成循环调用:不能出现 A 调用 BB 又调用 A 的情况,否则会导致栈溢出错误(StackOverflowError)。

使用 this() 重构上面的例子

现在我们用 this() 来优化 Student 类:

Java构造函数中this到底该怎么用?-图3
(图片来源网络,侵删)
public class Student {
    private String name;
    private int age;
    private String school;
    // 构造函数1:提供所有信息的“全参数”构造函数
    public Student(String name, int age, String school) {
        this.name = name;
        this.age = age;
        this.school = school;
        System.out.println("全参数构造函数被调用");
    }
    // 构造函数2:只提供 name 和 age
    // 它通过 this() 调用全参数构造函数,并将 school 设置为默认值 "Unknown"
    public Student(String name, int age) {
        // 1. this() 必须是第一行
        this(name, age, "Unknown");
        // 2. 这里的代码将在被调用的全参数构造函数执行完毕后执行
        System.out.println("两参数构造函数被调用");
    }
    // 构造函数3:只提供 name
    // 它通过 this() 调用两参数构造函数
    public Student(String name) {
        // 1. this() 必须是第一行
        this(name, 18); // 默认年龄为 18
        // 2. 这里的代码将在被调用的两参数构造函数执行完毕后执行
        System.out.println("单参数构造函数被调用");
    }
    // Getter 方法
    public String getName() { return name; }
    public int getAge() { return age; }
    public String getSchool() { return school; }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school='" + school + '\'' +
                '}';
    }
    // 主方法,用于测试
    public static void main(String[] args) {
        System.out.println("--- 创建学生1 ---");
        Student s1 = new Student("Alice", 20, "Harvard");
        System.out.println(s1);
        System.out.println("\n--- 创建学生2 ---");
        Student s2 = new Student("Bob", 22);
        System.out.println(s2);
        System.out.println("\n--- 创建学生3 ---");
        Student s3 = new Student("Charlie");
        System.out.println(s3);
    }
}

执行结果:

--- 创建学生1 ---
全参数构造函数被调用
Student{name='Alice', age=20, school='Harvard'}
--- 创建学生2 ---
全参数构造函数被调用
两参数构造函数被调用
Student{name='Bob', age=22, school='Unknown'}
--- 创建学生3 ---
全参数构造函数被调用
两参数构造函数被调用
单参数构造函数被调用
Student{name='Charlie', age=18, school='Unknown'}

从结果可以看出,当我们创建 s2 时,new Student("Bob", 22) 实际上执行了 new Student("Bob", 22, "Unknown") 的逻辑,同样,创建 s3 时,执行了完整的初始化链,这样,所有的初始化逻辑都集中在“全参数构造函数”中,其他构造函数只需通过 this() 调用它即可,避免了代码重复。


this()this 的区别

这是一个非常常见的混淆点,需要明确区分:

特性 this() (构造函数调用) this (关键字)
含义 调用同一个类另一个构造函数 指代当前对象的引用。
用途 在构造函数内部,用于初始化代码复用。 区分成员变量和局部变量。
在非静态方法中引用当前对象。
将当前对象作为参数传递给其他方法。
位置 只能出现在构造函数的第一行 可以出现在类的任何非静态方法中,或者作为构造函数参数。
示例 this(name, age); this.name = name;

示例:同时使用两者

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        // 这里的 this.name 是成员变量
        // 这里的 name 是构造函数的参数
        // 使用 this 关键字来区分和赋值
        this.name = name; 
        this.age = age;
    }
    public void printInfo() {
        // 在非静态方法中,this 可以省略,但写上更清晰
        System.out.println("Name: " + this.name + ", Age: " + this.age);
    }
}

this() 是 Java 构造函数中一个强大且重要的特性。

  1. 目的:实现构造函数间的代码复用,确保初始化逻辑的统一和简洁。
  2. 语法this(参数列表);
  3. 核心规则
    • 必须位于构造函数的第一行
    • 不能与 super() 同时使用。
  4. 好处:减少了代码冗余,提高了代码的可维护性,使类的结构更清晰。

通过合理使用 this(),你可以构建出更优雅、更健壮的 Java 类。

分享:
扫描分享到社交APP
上一篇
下一篇