`this` 关键字的用法:区分成员变量与局部变量,构造器互相调用

好的,没问题。下面是一篇关于 this 关键字用法的技术文章,希望能够满足您的要求。

this:Java世界里的“我”,你真的懂吗?

各位看官,今天咱们来聊聊Java世界里一个非常重要,但又常常让人摸不着头脑的关键字——this。 别看它只有四个字母,但它的作用可大了,搞明白了它,你就能在Java的世界里更加游刃有余。

想象一下,你在一个聚会上,人很多,你想要跟某个人打招呼,但是屋子里有好几个同名同姓的人。 你怎么区分你想打招呼的到底是哪一个呢? 你可能会说:“喂,穿红衣服的那个张三!” 或者“喂,昨天借我钱的那个李四!”

在Java里,this 就扮演着类似的角色,它帮助我们区分不同的“自己”。 别急,咱们慢慢道来。

this 的第一重身份:区分成员变量与局部变量

咱们先来看一个最常见的场景:区分成员变量和局部变量。 啥是成员变量? 啥又是局部变量呢?

简单来说,成员变量就是定义在类里,方法之外的变量,它们属于对象,也称为实例变量。 局部变量则是定义在方法里面的变量,它们只在方法内部有效。

public class Person {
    private String name; // 成员变量

    public void setName(String name) { // name 是局部变量
        // this.name = name;  // 使用 this 区分成员变量和局部变量
        name = name; // 错误! 局部变量赋值给局部变量,成员变量没变
    }

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        Person person = new Person();
        person.setName("张三");
        System.out.println(person.getName()); // 输出 null,因为成员变量 name 没有被赋值
    }
}

在这个例子中,name既是成员变量,也是setName方法的局部变量。 如果我们直接写 name = name; Java会认为你是把局部变量name的值赋给它自己,成员变量name的值根本没有改变。

这时候,this 就派上用场了。 我们可以这样写:

public class Person {
    private String name; // 成员变量

    public void setName(String name) { // name 是局部变量
        this.name = name;  // 使用 this 区分成员变量和局部变量
    }

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        Person person = new Person();
        person.setName("张三");
        System.out.println(person.getName()); // 输出 张三,因为成员变量 name 被赋值了
    }
}

this.name = name; 这条语句告诉Java:“嘿,伙计,等号左边的name是指这个对象(this)的成员变量name,等号右边的name是指setName方法接收的那个局部变量name。”

这样,Java就能准确地把局部变量name的值赋给成员变量name了。

总结一下: 当成员变量和局部变量同名时,使用 this.变量名 可以明确地引用成员变量。

this 的第二重身份:构造器互相调用

除了区分变量,this 还有一个更高级的用法:在构造器中调用其他的构造器。 啥是构造器? 简单来说,构造器就是用来创建对象的特殊方法。

一个类可以有多个构造器,它们可以有不同的参数列表。 有时候,我们希望在一个构造器里调用另一个构造器,以避免重复的代码。 这时候,this() 就派上用场了。

public class Student {
    private String name;
    private int age;
    private String address;

    public Student() {
        this("未知姓名", 18, "未知地址"); // 调用带参数的构造器
        System.out.println("无参构造器被调用");
    }

    public Student(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
        System.out.println("带参数的构造器被调用");
    }

    public static void main(String[] args) {
        Student student = new Student(); // 调用无参构造器
        System.out.println(student.name); // 输出:未知姓名
    }
}

在这个例子中,无参构造器 Student() 使用 this("未知姓名", 18, "未知地址"); 调用了带三个参数的构造器。 这样做的好处是,我们可以避免在无参构造器里重复编写初始化 name, age, address 的代码。

注意:

  • this() 必须是构造器里的第一条语句。
  • 一个构造器只能调用一个其他的构造器。
  • 不能在一个构造器里同时调用两个或以上的其他构造器。

再来一个例子,加深理解:

public class Rectangle {
    private int width;
    private int height;

    public Rectangle() {
        this(10, 5); // 调用带参数的构造器,默认宽高为10和5
    }

    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public int getArea() {
        return width * height;
    }

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle(); // 调用无参构造器
        System.out.println("矩形面积:" + rectangle.getArea()); // 输出:矩形面积:50
        Rectangle rectangle2 = new Rectangle(20, 10); // 调用带参数的构造器
        System.out.println("矩形面积:" + rectangle2.getArea()); // 输出:矩形面积:200
    }
}

在这个例子中,无参构造器 Rectangle() 调用了带两个参数的构造器,并设置了默认的宽高。 这样,当我们使用无参构造器创建 Rectangle 对象时,它会自动使用默认的宽高。

总结一下: 使用 this() 可以在一个构造器里调用其他的构造器,以避免代码重复,提高代码的复用性。

this 的第三重身份:指向当前对象

this 关键字还有一个重要的作用,那就是指向当前对象。 啥意思呢? 就是说,在任何非静态方法中,this 都代表调用该方法的对象。

public class Dog {
    private String name;

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

    public void bark() {
        System.out.println(this.name + " 在汪汪叫!"); // this 指向调用 bark() 方法的 Dog 对象
    }

    public static void main(String[] args) {
        Dog dog1 = new Dog("旺财");
        Dog dog2 = new Dog("小黑");

        dog1.bark(); // 输出:旺财 在汪汪叫!
        dog2.bark(); // 输出:小黑 在汪汪叫!
    }
}

在这个例子中,bark() 方法里的 this.name 指向的是调用 bark() 方法的 Dog 对象的名字。 当 dog1 调用 bark() 方法时,this 指向 dog1,所以输出的是 "旺财 在汪汪叫!"。 当 dog2 调用 bark() 方法时,this 指向 dog2,所以输出的是 "小黑 在汪汪叫!"。

再来一个例子:

public class Counter {
    private int count = 0;

    public Counter increment() {
        count++;
        return this; // 返回当前对象
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {
        Counter counter = new Counter();
        counter.increment().increment().increment(); // 链式调用
        System.out.println("计数器的值:" + counter.getCount()); // 输出:计数器的值:3
    }
}

在这个例子中,increment() 方法返回 this,也就是返回当前 Counter 对象。 这样我们就可以进行链式调用,连续调用 increment() 方法。 这种技巧在很多框架和库中都有应用,可以使代码更加简洁易读。

总结一下: this 在非静态方法中指向当前对象,我们可以利用它来访问对象的成员变量,调用对象的方法,甚至返回对象本身。

this 的注意事项

  • this 只能在非静态方法中使用。 静态方法属于类,不属于对象,所以静态方法里没有 this
  • 在构造器中使用 this() 调用其他构造器时,this() 必须是构造器里的第一条语句。
  • this 不能被赋值。 this 是一个指向当前对象的引用,我们不能改变它的指向。

总结

好了,各位看官,今天咱们一起深入地探讨了 this 关键字的用法。 this 就像Java世界里的“我”,它可以帮助我们区分成员变量和局部变量,在构造器中调用其他构造器,指向当前对象。 掌握了 this,你就能在Java的世界里更加游刃有余,写出更加清晰、简洁、高效的代码。

为了方便大家记忆,我把 this 的用法总结成一个表格:

用法 作用 示例
区分成员变量与局部变量 当成员变量和局部变量同名时,使用 this.变量名 可以明确地引用成员变量。 java public class Person { private String name; public void setName(String name) { this.name = name; } }
构造器互相调用 使用 this() 可以在一个构造器里调用其他的构造器,以避免代码重复,提高代码的复用性。 java public class Student { public Student() { this("未知姓名", 18, "未知地址"); } public Student(String name, int age, String address) { this.name = name; this.age = age; this.address = address; } }
指向当前对象 在非静态方法中,this 指向当前对象,我们可以利用它来访问对象的成员变量,调用对象的方法,甚至返回对象本身。 java public class Dog { private String name; public void bark() { System.out.println(this.name + " 在汪汪叫!"); } } public class Counter { public Counter increment() { count++; return this; } }

希望这篇文章能够帮助你更好地理解 this 关键字。 记住,实践是检验真理的唯一标准,多写代码,多思考,你一定能够掌握 this 的精髓! 下次有机会再和大家聊聊Java的其他有趣的话题。 拜拜!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注