首页 / Java 入门教程 / this 关键字

Java 入门教程

this 关键字

本教程共 100 篇 · 第 34 篇 · 更新于 2026-08-05 · 约 14 分钟阅读

JavaJava 入门教程this当前对象构造调用

本节目标:理解 this 代表”当前对象自己”,学会用它区分同名的成员变量和局部变量、在构造里调用其他构造、把当前对象传给别处。

this 翻译过来就是”这个”。在 Java 里,它指代当前正在调用方法的那个对象。谁调用,this 就是谁。

this 指代当前对象

public class Student {
    String name;

    void show() {
        System.out.println(this.name);   // this 指调用 show 的那个学生
    }
}

s1.show() 时,this 就是 s1;s2.show() 时,this 就是 s2。所以 this 让方法知道”我属于哪个对象”。

Note

同一个方法被不同对象调用,this 指向就不同。这就是为什么每个对象能维护自己的状态——方法里操作的都是”当前对象”的数据。

区分同名变量

最常见用法:局部变量(通常是构造/方法的参数)和成员变量同名时,用 this 指成员变量。

public class Student {
    String name;

    Student(String name) {      // 参数也叫 name
        this.name = name;       // this.name 是成员变量,右边 name 是参数
    }
}

不加 this,name = name 会把参数赋给参数自己,成员变量纹丝不动。这种写法在构造方法里天天见。

Warning

形参名和成员变量同名是推荐写法(可读性好),但一定要用 this. 点明成员变量,否则赋值无效。忘了 this 是初学者高频 bug。

方法里也能用 this

不只是构造方法,普通方法里参数和成员变量同名时也能用:

public class Student {
    String name;

    void setName(String name) {
        this.name = name;   // 左边成员变量,右边参数
    }
}

this 调用其他构造:this()

同一个类里,用 this(参数) 调用另一个构造方法,必须放在构造体第一行。

public class Student {
    String name;
    int age;

    Student() {
        this("未知");     // 调用单参构造
    }
    Student(String name) {
        this(name, 0);    // 调用双参构造
    }
    Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

这样三个构造串成一条链,真正的赋值逻辑只在最后那个写一遍。

Note

this()this.属性 都基于”当前对象”这个语义。前者省去重复写构造代码,后者解决命名冲突。记住一句话:this 就是”我这个对象”。

this() 的规则

  • 必须放在构造方法的第一行
  • 不能循环调用:A 调 B,B 又调 A,编译报错
  • 一个构造方法里只能调一次 this()
  • this()super() 不能同时出现在同一个构造方法里(都要求第一行)
// 错的示范:循环调用
Student() {
    this("x");       // 调第二个
}
Student(String name) {
    this();          // 又调第一个,循环!编译报错
}

把当前对象传出去

有时需要把”自己”传给别的方法,比如注册监听器:

void register() {
    someService.addListener(this);   // 把当前对象作为监听者传过去
}

这种”把自己交出去”的写法在事件处理、回调里很常见。

Warning

构造方法里不要急着把 this 传出去。对象还没构造完,外部就可能开始使用它,读到半初始化的状态。这是线程安全的隐患。建议构造完成后再注册或传递。

Tip

不用 this 也能跑的代码,就不必硬加 this(除了解决重名)。滥用 this 反而让代码变啰嗦。它的核心价值就两点:区分重名、串构造。

this 在 equals 里

重写 equals 方法时,this 代表当前对象,参数是另一个对象:

public class Student {
    String name;
    int age;

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;   // 同一个对象,直接相等
        if (!(obj instanceof Student)) return false;
        Student other = (Student) obj;
        return this.age == other.age && this.name.equals(other.name);
    }
}

this == obj 先判断是不是同一个引用,是的话直接返回 true,省去逐字段比较。

this 在 compareTo 里

实现 Comparable 接口时,this 是当前对象,参数是另一个:

public class Student implements Comparable<Student> {
    int score;

    @Override
    public int compareTo(Student other) {
        return this.score - other.score;   // 按分数升序
    }
}

this 在内部类里

内部类里 this 指内部类对象本身。如果想访问外部类的 this,用 外部类名.this

public class Outer {
    String name = "外部";

    class Inner {
        String name = "内部";

        void show() {
            System.out.println(name);          // 内部
            System.out.println(this.name);     // 内部
            System.out.println(Outer.this.name); // 外部
        }
    }
}

this 在 record 里(Java 16+)

record 是 Java 16 引入的不可变数据载体。this 在 record 里同样指当前实例:

public record Point(int x, int y) {
    double distanceToOrigin() {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    }
}

record 的字段默认 private final,this 访问它们和普通类一样。

this 在 switch 表达式里(Java 21+)

Java 21 引入了 switch 的 arrow 形式,this 的使用没有变化。但有个细节要注意——lambda 里的 this 和匿名内部类的 this 不一样:

public class Demo {
    String name = "demo";

    void testLambda() {
        Runnable r = () -> {
            System.out.println(this.name);   // 指外部类 Demo
        };
    }

    void testAnonymous() {
        Runnable r = new Runnable() {
            String name = "inner";
            @Override
            public void run() {
                System.out.println(this.name);   // 指匿名类自己
            }
        };
    }
}

lambda 里的 this 指向包含 lambda 的外部类,匿名内部类的 this 指向匿名类自己。这是常见面试坑。

this 在枚举里

枚举常量可以有自己的方法,this 指向当前枚举常量:

public enum Color {
    RED("#FF0000"),
    GREEN("#00FF00"),
    BLUE("#0000FF");

    private final String hex;

    Color(String hex) {
        this.hex = hex;
    }

    public String getHex() {
        return this.hex;   // 返回当前枚举常量的 hex
    }
}

this 在密封类里(Java 17+)

密封类(sealed class)控制谁能继承它。this 在密封类里的行为和普通类一样:

public sealed class Shape permits Circle, Rectangle {
    double area() {
        return switch (this) {   // Java 21+ 的 pattern matching
            case Circle c    -> Math.PI * c.radius() * c.radius();
            case Rectangle r -> r.width() * r.height();
        };
    }
}

this 在方法链式调用里的应用

Builder 模式是 this 返回的经典场景:

public class HttpClient {
    private String url;
    private int timeout;

    public HttpClient url(String url) {
        this.url = url;
        return this;   // 返回当前对象,支持链式调用
    }

    public HttpClient timeout(int timeout) {
        this.timeout = timeout;
        return this;
    }
}

// 使用:链式调用,一气呵成
new HttpClient().url("https://example.com").timeout(5000);

每个 setter 返回 this,就能连续调用。这是 this 在实际工程里的高频用法。

this 与线程安全

this 本身不涉及线程安全,但”把 this 传出去”要注意:对象还没构造完就把 this 传给其他线程,可能看到半初始化的状态。

public class Student {
    String name;

    Student(String name) {
        this.name = name;
        GlobalEventBus.register(this);   // 危险!对象还没构造完
    }
}

构造方法里把 this 传给外部,外部可能在构造完成前就用这个对象,读到不完整的状态。建议构造完成后再注册。

this 在函数式接口里的陷阱

lambda 表达式里 this 指向外部类,这会导致一个常见陷阱——在 lambda 里调用 this.equals() 实际调用的是外部类的 equals,而不是 lambda 自身:

public class Demo {
    void test() {
        Runnable r = () -> {
            // this 指 Demo 实例,不是 Runnable 实例
            System.out.println(this.getClass());   // class Demo
        };
    }
}

如果需要在匿名内部类里访问自身,直接用 this;如果要访问外部类的 this,用 外部类名.this

速查表

用法写法场景
访问成员变量this.name区分同名参数
调用其他构造this(参数)构造链,必须第一行
传当前对象method(this)监听器、回调
判断同一引用this == objequals 开头
外部类 thisOuter.this内部类访问外部
返回当前对象return this链式调用 Builder
枚举方法内this.hex访问当前枚举常量

常见疑问

Q:静态方法里能用 this 吗? 不能。静态方法属于类,不依赖对象,没有”当前对象”的概念。静态方法里写 this 会编译报错。

Q:this 能当返回值吗? 能。return this 返回当前对象,常用于”链式调用”(Builder 模式)。比如 new Builder().setA(1).setB(2).build(),每个 setter 都返回 this。

Q:lambda 表达式里 this 指什么? lambda 里的 this 和外面方法里的 this 一样,指包含 lambda 的对象实例。这点和匿名内部类不同——匿名内部类的 this 指匿名类自己。

Q:构造方法里 this() 和 this. 能同时用吗? 不能。this() 必须放在构造方法第一行,后面不能再有 this()。但 this() 调用之后可以用 this.属性 给成员变量赋值。比如 this("未知"); this.age = 0; 是合法的。

Q:this 能当参数传给父类构造吗? 不能。super() 必须放在构造方法第一行,this() 也必须放第一行,两者冲突。所以不能在 super() 之前或之后用 this(),也不能把 this 传给 super()

Q:this 在泛型类里能用吗? 能。泛型类的 this 和普通类一样,指当前实例。泛型类型参数不影响 this 的语义。比如 Box<T> { void set(T val) { this.value = val; } } 完全合法。