this 关键字
this 关键字在 Java 中代表当前对象的引用,它可以在类的方法或构造器中使用,主要有以下几个用途:

访问当前对象的成员变量(解决命名冲突)
当方法的形参与类的成员变量同名时,为了避免混淆,可以使用 this 来明确指定访问的是成员变量。
public class Person {
private String name;
// 构造器
public Person(String name) {
// 这里的 name 是形参,this.name 是成员变量
// 将形参 name 的值赋给成员变量 name
this.name = name;
}
public void printName() {
// 这里的 name 默认是成员变量
System.out.println("Name: " + this.name); // 使用 this 更清晰,但也可以省略
}
}
分析:
在构造器 public Person(String name) 中,name 是一个局部变量(形参),如果直接写 name = name;,赋值操作会自己给自己赋值,成员变量 name 的值不会被改变,使用 this.name 就明确表示我们要给当前对象的 name 成员变量赋值。
调用当前对象的成员方法
通常我们直接调用成员方法,printName();,但有时为了代码清晰,或者在某些特殊场景下,可以使用 this 来显式调用。
public class Person {
public void sayHello() {
System.out.println("Hello from Person!");
}
public void greet() {
// 直接调用
sayHello();
// 使用 this 显式调用,效果相同
this.sayHello();
}
}
调用当前类的其他构造器(构造器重载)
在一个类的构造器中,可以使用 this(...) 来调用该类的其他构造器,这通常用于代码复用,避免在多个构造器中重复编写初始化代码。

重要规则:
this(...)必须是构造器中的第一条语句。- 不能在一个构造器中同时调用
this(...)和super(...)。
public class Student {
private String name;
private int age;
// 构造器1:只提供名字
public Student(String name) {
// 调用构造器2,并传入默认年龄 18
this(name, 18);
System.out.println("Constructor 1 (name only)");
}
// 构造器2:提供名字和年龄
public Student(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Constructor 2 (name and age)");
}
public void displayInfo() {
System.out.println("Name: " + this.name + ", Age: " + this.age);
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student("Alice"); // 会调用构造器1
s1.displayInfo(); // 输出: Name: Alice, Age: 18
Student s2 = new Student("Bob", 25); // 会调用构造器2
s2.displayInfo(); // 输出: Name: Bob, Age: 25
}
}
执行流程分析:
- 创建
s1时,new Student("Alice")调用了构造器1。 - 构造器1的第一条语句是
this("Alice", 18);,所以它立即停止执行,转而去调用构造器2。 - 构造器2执行完毕后,返回到构造器1,继续执行
System.out.println(...)。 s1的最终状态是name="Alice",age=18。
super 关键字
super 关键字代表当前对象的父类对象的引用,它主要用于在子类中访问父类的成员(变量、方法、构造器)。
访问父类的成员变量(解决命名冲突)
当子类的成员变量与父类的成员变量同名时,可以使用 super 来访问父类的成员变量。

class Animal {
protected String name = "Animal";
}
class Dog extends Animal {
private String name = "Dog";
public void printNames() {
System.out.println("Dog's name: " + this.name); // 访问子类的 name
System.out.println("Animal's name: " + super.name); // 访问父类的 name
}
}
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.printNames();
}
}
输出:
Dog's name: Dog
Animal's name: Animal
调用父类的成员方法
当子类重写了父类的方法时,如果想在子类的方法中调用父类的原始版本,可以使用 super。
class Vehicle {
public void move() {
System.out.println("Vehicle is moving.");
}
}
class Car extends Vehicle {
@Override
public void move() {
// 先调用父类的 move 方法
super.move();
// 再添加自己的行为
System.out.println("Car is driving on the road.");
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.move();
}
}
输出:
Vehicle is moving.
Car is driving on the road.
调用父类的构造器
在创建子类对象时,JVM 会先隐式或显式地调用父类的构造器,来初始化父类继承下来的成员,使用 super(...) 可以显式地指定调用父类的哪个构造器。
重要规则:
super(...)必须是子类构造器中的第一条语句。- 如果子类构造器中没有显式调用
super(...),编译器会自动添加一个super();来调用父类的无参构造器。 - 如果父类没有无参构造器,而子类也没有显式调用
super(...),则编译会出错。
class Father {
public Father() {
System.out.println("Father's no-arg constructor");
}
public Father(String message) {
System.out.println("Father's arg constructor: " + message);
}
}
class Son extends Father {
// 子类构造器1:隐式调用父类的无参构造器
public Son() {
// 等价于 super(); (必须放在第一行)
System.out.println("Son's no-arg constructor");
}
// 子类构造器2:显式调用父类的带参构造器
public Son(String message) {
super("Hello from Son"); // 显式调用,必须放在第一行
System.out.println("Son's arg constructor");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("--- Creating Son object 1 ---");
Son s1 = new Son();
System.out.println();
System.out.println("--- Creating Son object 2 ---");
Son s2 = new Son("Custom Message");
}
}
输出:
--- Creating Son object 1 ---
Father's no-arg constructor
Son's no-arg constructor
--- Creating Son object 2 ---
Father's arg constructor: Hello from Son
Son's arg constructor
this 与 super 的核心区别与联系
| 特性 | this |
super |
|---|---|---|
| 含义 | 当前对象的引用 | 当前对象父类对象的引用 |
| 指向 | 指向本类的对象 | 指向父类的对象 |
| 使用场景 | 访问本类成员变量(解决重名) 访问本类成员方法 调用本类其他构造器 |
访问父类成员变量(解决重名) 调用父类成员方法 调用父类构造器 |
| 构造器调用 | this(...) |
super(...) |
| 位置限制 | 必须在构造器第一条语句 | 必须在构造器第一条语句 |
| 与继承关系 | 不依赖于继承,任何类都可以使用 | 只在继承关系中才有意义 |
总结与最佳实践
- 明确指向:
this指向自己,super指向父亲,记住这个核心区别,就不会用混。 - 构造器链:在继承体系中,对象的创建是一个自上而下的过程,父类先被初始化,然后才是子类。
super是这个链条的显式体现。 - 代码清晰:虽然有时
this或super可以省略(如访问成员变量),但在容易产生混淆的地方(如构造器、形参与成员变量同名时),显式写出它们可以让代码更清晰、更易于维护。 - 构造器规则:牢记
this(...)和super(...)都必须是构造器中的第一条语句,并且不能同时出现,这是 Java 语言硬性规定的语法。
理解 this 和 super 是掌握 Java 面向对象编程,特别是继承机制的关键,它们是连接类与类、对象与对象之间关系的桥梁。
