社交媒体

this 关键字

this 关键字

钩子

先看一段很多新手写过的代码:

class Student {
    String name;

    void setName(String name) {
        name = name;    // 想给字段赋值
    }
}

编译通过,运行不报错,但什么都没发生——对象的名字还是 null。

因为 name = name 里,左右两边都是参数 name,自己赋给自己,字段从头到尾没被碰过。Java 对此的解法只有一个字:this——"我自己"。

用法 1:this.属性——"我的"xxx

void setName(String name) {
    this.name = name;   // this.name 是字段,name 是参数
}

this 代表当前执行这个方法的对象自己。s1 调用 setName 时,this 就是 s1;s2 调用时,this 就是 s2。

读法很简单:带 this 的 = "我的",不带 = "就近的"(参数 > 字段)。构造方法里的 this.name = name 同理——上篇那个重复写三遍的赋值,理解了 this 就不神秘了。

16-this.name指向图.png

用法 2:this(...)——构造方法之间互相帮忙

上篇末尾的重复问题:三个构造方法都在写 this.name = name。用 this() 解决:

class Student {
    String name;
    int age;

    Student() {
        this("无名氏", 0);        // 借用下面的三参构造
    }

    Student(String name) {
        this(name, 0);           // 借用三参构造
    }

    Student(String name, int age) {   // 真正干活的只有这一个
        this.name = name;
        this.age = age;
    }
}

this(...) 意思是"调用本类的另一个构造方法",赋值逻辑只写一遍,其他构造负责转发。

两条铁规矩:

  1. this(...) 必须是构造方法的第一行,不然编译报错——对象还没"接生"完,不能先干别的;
  2. 不能两个构造方法互相调用,会形成死循环,编译器直接拦截。

用法 3:return this——链式调用的秘密

方法也可以把"我自己"还回去:

class StringBuilder2 {
    String content = "";

    StringBuilder2 append(String s) {
        content = content + s;
        return this;          // 把"我自己"返回
    }
}

于是可以这样连着写:

new StringBuilder2().append("橙码").append("酱").append("真棒");
// 每次返回自己,所以能一直 . 下去

这就是链式调用。你之后天天见到的 StringBuilder、StringBuffer 都是这套机制——"为什么 StringBuilder 能一直 .append 下去",今天你有了标准答案。

16-链式调用流程图.png

收尾:三种用法一句话总结

写法 意思 场景
this.name 我的字段 参数和字段同名时区分
this(...) 调本类另一个构造 构造方法复用,必须第一行
return this 返回我自己 链式调用

this 不玄,就是"我自己"三个字。第 20 篇讲接口时,你会第三次见到它,越来越熟。


本文示例代码均已本地实测通过,可直接运行。
对应文件:ThisDemo.java


橙码酱,分享更有用的技术知识,助你成为更优秀的开发者。