杰瑞科技汇

Java中this与super到底该怎么用?

this 关键字

this 在 Java 中是一个引用变量,它指向当前对象,哪个对象调用了方法,this 就代表哪个对象。

Java中this与super到底该怎么用?-图1
(图片来源网络,侵删)

this 主要有以下几个用途:

区分成员变量和局部变量

当方法的参数名与类的成员变量名相同时,为了避免混淆,我们可以使用 this 来明确引用成员变量。

示例:

public class Person {
    private String name; // 成员变量
    // 构造方法,参数 name 是局部变量
    public Person(String name) {
        // 这里的 this.name 指的是类的成员变量
        // 右边的 name 指的是构造方法的参数
        this.name = name; 
    }
    public void printName() {
        System.out.println(this.name); // this.name 明确指代成员变量
    }
}
public class Main {
    public static void main(String[] args) {
        Person p = new Person("张三");
        p.printName(); // 输出: 张三
    }
}

代码解析: 在构造方法 Person(String name) 中,如果直接写 name = name;,其实是将局部变量 name 赋值给了它自己,成员变量 name 的值并没有被改变,使用 this.name 就能明确地将参数 name 的值赋给成员变量 name

Java中this与super到底该怎么用?-图2
(图片来源网络,侵删)

调用当前类的其他构造方法

在一个类的构造方法中,可以使用 this(...) 来调用同一个类的其他重载构造方法,这通常用于减少代码重复,将公共的初始化逻辑放在一个主构造方法中。

规则:

  • this(...) 必须是构造方法中的第一条语句
  • 不能在一个构造方法中同时使用 this(...)super(...)

示例:

public class Student {
    private String name;
    private int age;
    // 构造方法1:无参构造
    public Student() {
        // 调用构造方法2,并传入默认值
        this("未知姓名", 18); 
        System.out.println("无参构造方法被调用");
    }
    // 构造方法2:带参构造
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("带参构造方法被调用");
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
}
public class Main {
    public static void main(String[] args) {
        Student s1 = new Student(); 
        // 输出:
        // 带参构造方法被调用
        // 无参构造方法被调用
        System.out.println(s1); // 输出: Student [name=未知姓名, age=18]
    }
}

代码解析: 创建 Student 对象时,new Student() 调用了无参构造方法,无参构造方法中的第一行代码 this("未知姓名", 18); 又调用了带参构造方法,完成了 nameage 的初始化。

Java中this与super到底该怎么用?-图3
(图片来源网络,侵删)

将当前对象作为参数传递给其他方法

public class A {
    public void method(A a) {
        System.out.println("A类的method方法被调用,传入的对象是: " + a);
    }
    public void callMethod() {
        // 将当前对象 (this) 作为参数传递给 method
        this.method(this); 
    }
}
public class Main {
    public static void main(String[] args) {
        A a = new A();
        a.callMethod(); 
        // 输出: A类的method方法被调用,传入的对象是: A@15db9742 (对象的地址)
    }
}

super 关键字

super 关键字用于访问和操作父类的成员(变量、方法)和构造方法,它不是一个对象的引用,而是一个指示编译器调用父类成员的特殊关键字。

super 主要有以下几个用途:

访问父类的成员变量

当子类的成员变量与父类的成员变量同名时,使用 super 来访问父类的成员变量。

示例:

class Animal {
    String name = "动物";
}
class Dog extends Animal {
    String name = "狗";
    public void printNames() {
        System.out.println("子类的name: " + this.name); // 使用 this 访问子类自己的
        System.out.println("父类的name: " + super.name); // 使用 super 访问父类的
    }
}
public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.printNames();
        // 输出:
        // 子类的name: 狗
        // 父类的name: 动物
    }
}

调用父类的方法

当子类重写了父类的方法,但有时需要在子类中调用父类的原始版本时,可以使用 super.methodName()

示例:

class Vehicle {
    public void move() {
        System.out.println("车辆在移动");
    }
}
class Car extends Vehicle {
    @Override
    public void move() {
        // 先调用父类的 move 方法
        super.move(); 
        System.out.println("汽车在公路上行驶");
    }
}
public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.move();
        // 输出:
        // 车辆在移动
        // 汽车在公路上行驶
    }
}

调用父类的构造方法

这是 super 最重要和最常见的用途,子类在创建对象时,会先调用父类的构造方法,来初始化从父类继承来的成员。

规则:

  • 如果子类构造方法中没有显式地调用 super(...),Java 编译器会自动在构造方法的第一行添加一个 super(); 来调用父类的无参构造方法。
  • 如果父类没有无参构造方法,那么子类必须显式地使用 super(...) 来调用父类的某个有参构造方法,否则会编译错误。
  • super(...) 必须是子类构造方法中的第一条语句

示例:

class Father {
    private String name;
    // 父类的有参构造方法
    public Father(String name) {
        this.name = name;
        System.out.println("父类 Father 的构造方法被调用,name: " + name);
    }
}
class Son extends Father {
    public Son() {
        // 必须显式调用父类的构造方法
        // 因为父类没有无参构造方法,编译器不会自动添加 super()
        super("儿子"); 
        System.out.println("子类 Son 的构造方法被调用");
    }
}
public class Main {
    public static void main(String[] args) {
        Son son = new Son();
        // 输出:
        // 父类 Father 的构造方法被调用,name: 儿子
        // 子类 Son 的构造方法被调用
    }
}

代码解析: 创建 Son 对象时,会先执行 Son 的构造方法,由于 Son 的构造方法第一行是 super("儿子");,所以会立即暂停 Son 的构造过程,去调用 Father 的构造方法。Father 的构造方法执行完毕后,再返回到 Son 的构造方法继续执行。


thissuper 的核心区别与联系

特性 this super
含义 指向当前对象的引用。 访问父类成员(变量、方法、构造方法)的关键字。
访问成员 访问当前类的成员。 访问父类的成员(当子类与父类成员同名时)。
调用构造方法 调用当前类的其他构造方法 this(...) 调用父类的构造方法 super(...)
与继承关系 与继承无关,任何一个类都有 this 与继承紧密相关,只能在有继承关系的子类中使用。
使用位置 在方法或构造方法内部。 在方法或构造方法内部。
构造方法中的位置 必须是第一条语句。 必须是第一条语句。

核心联系:

  1. 构造方法链:在创建子类对象时,super 会确保父类的构造方法被调用,从而形成一个从父类到子类的构造方法调用链,这是 Java 实现继承时初始化对象的基础。
  2. thissuper 不能同时出现在构造方法的第一行:因为它们都要求是第一条语句,这是互斥的。
  • this:代表“我自己”,主要用于处理当前对象内部的逻辑,比如区分同名变量、调用自身其他构造方法。
  • super:代表“我的父类”,主要用于处理继承关系,比如访问父类被隐藏的成员、调用父类的方法、以及最重要的——调用父类的构造方法来确保父类部分得到正确初始化。

理解 thissuper 是掌握 Java 面向对象编程,特别是继承机制的关键一步,务必记住它们在构造方法中的特殊规则和作用。

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