super与this关键字

核心概念

superthis是Java中用于引用当前对象和父类对象的关键字。它们在构造函数、方法调用和变量访问中扮演着重要角色,深入理解它们的用法是掌握Java面向对象编程的关键。


一、this关键字

1.1 基本用法

public class ThisDemo {
    private String name;
    private int age;

    // 1. 区分同名参数和成员变量
    public ThisDemo(String name, int age) {
        this.name = name;  // this指当前对象的成员变量
        this.age = age;
    }

    // 2. 调用同类的其他构造函数
    public ThisDemo() {
        this("Default", 0);  // 调用另一个构造函数
    }
}

1.2 方法链和返回当前对象

public class MethodChainDemo {
    private int value;

    // 链式调用
    public MethodChainDemo setValue(int value) {
        this.value = value;
        return this;  // 返回当前对象
    }

    public MethodChainDemo increment() {
        this.value++;
        return this;
    }

    public int getValue() {
        return value;
    }
}

// 使用
MethodChainDemo demo = new MethodChainDemo()
    .setValue(10)
    .increment()
    .increment();

二、super关键字

2.1 调用父类构造函数

public class Parent {
    protected String name;

    public Parent(String name) {
        this.name = name;
    }
}

public class Child extends Parent {
    private int age;

    // 必须显式调用父类构造函数
    public Child(String name, int age) {
        super(name);  // 调用父类构造函数
        this.age = age;
    }
}

2.2 访问父类方法

public class Parent {
    public void method() {
        System.out.println("Parent method");
    }
}

public class Child extends Parent {
    @Override
    public void method() {
        super.method();  // 调用父类方法
        System.out.println("Child method");
    }
}

2.3 访问父类字段

public class Parent {
    protected String name = "Parent";
}

public class Child extends Parent {
    private String name = "Child";

    public void printName() {
        System.out.println(this.name);     // Child
        System.out.println(super.name);    // Parent
    }
}

三、构造函数调用

3.1 构造函数调用顺序

public class InitializationDemo {
    public InitializationDemo() {
        // 1. 隐式调用父类无参构造函数
        // 2. 执行初始化块
        // 3. 执行构造函数体
    }

    public InitializationDemo(int value) {
        // 显式调用另一个构造函数
        this();
    }
}

3.2 复杂继承场景

public class GrandParent {
    public GrandParent() {
        System.out.println("GrandParent Constructor");
    }
}

public class Parent extends GrandParent {
    public Parent() {
        System.out.println("Parent Constructor");
    }
}

public class Child extends Parent {
    public Child() {
        // 隐式调用 super()
        System.out.println("Child Constructor");
    }
}

// 调用顺序
new Child();
// 输出:
// GrandParent Constructor
// Parent Constructor
// Child Constructor

四、高频面试题

Q1: this和super有什么区别?

答:

  • this:引用当前对象
  • super:引用父类对象
  • this可调用本类方法/构造函数
  • super可调用父类方法/构造函数

Q2: 构造函数中this()和super()的区别?

答:

  • this():调用同一个类的其他构造函数
  • super():调用父类的构造函数
  • 必须在构造函数的第一行
  • 不能同时使用

Q3: 为什么构造函数调用super()或this()必须在第一行?

答:

  • 确保父类正确初始化
  • 防止使用未初始化的成员
  • 保证对象的完整性和一致性

Q4: 可以在static方法中使用this吗?

答:

  • 不可以
  • static方法属于类,不属于具体对象
  • 没有this引用

Q5: 父类私有方法能否被子类重写?

答:

  • 不能被重写
  • 子类可以定义同名方法,但这是隐藏,不是重写
  • 父类私有方法对子类不可见

五、最佳实践

✅ 推荐做法

// 1. 构造函数链
public class User {
    private String name;
    private int age;

    public User() {
        this("Default", 0);
    }

    public User(String name) {
        this(name, 0);
    }

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

// 2. 方法链
public class Builder {
    private String name;
    private int age;

    public Builder setName(String name) {
        this.name = name;
        return this;
    }

    public Builder setAge(int age) {
        this.age = age;
        return this;
    }

    public User build() {
        return new User(name, age);
    }
}

❌ 避免做法

// 1. 避免过度使用this
public class BadDesign {
    private String name;

    public void method() {
        // 不必要的this
        this.name = "test";  // 可以直接 name = "test"
    }
}

// 2. 避免在构造函数中过度调用
public class ComplexConstructor {
    public ComplexConstructor() {
        this(1);
        this(1, "test");  // ❌ 错误:不能多次调用this()
    }
}

相关链接


记忆口诀

this指向当前对象,成员变量要区分
构造函数链式调用,方法返回自身身
super访问父类成员,构造函数必第一
继承体系初始化,父类先行子类随

相关笔记

super关键字super深层剖析 从字节码/调用链角度把 super 挖得更深(本篇偏使用规则),拿不准时去那边看底层。


⬅️ static关键字 🏠 00-Java ➡️ 其他关键字