在 CodeGym 上,学生们从第一节课开始就按字面意思向学生介绍了 Java this关键字。随着时间的推移,它的含义变得清晰。但回过头来看,估计很多人都承认自己很长一段时间都无法理解这个关键词的禅意。本文将为任何尚未能够这样做的人揭开this关键字秘密的面纱......我有Schildt 的 Java 参考资料,然后在第 171 页你可以看到this关键字方法需要引用调用它的对象。我们可以以此结束课程。但我们需要细节。通常,您需要在两种情况下使用它:
所以事实证明您只是将方法的名称变量分配给它自己。这当然没有任何意义。因此,该语言需要某种方式来区分Human类的名称变量和setName方法中的名称变量。通过引入this关键字解决了这个问题,在这种情况下,它表示您打算引用与Human类的实例关联的变量,而不是方法中的变量: 换句话说,this
指的是调用对象,正如我们在文章开头提到的。结果,setName方法在创建的对象上设置了人名。下面是不使用this关键字的程序代码。该代码创建了一个Human对象并为其分配了一个名称: 下面是带有this
关键字的代码:
- 当实例变量和方法/构造函数变量具有相同的名称时;
- 当您需要从另一种类型的构造函数调用特定类型的构造函数(例如,默认构造函数或参数化构造函数)时。这也称为显式构造函数调用。
示例 1:实例变量和方法变量具有相同的名称。
假设我们有一个定义 name 字段的Human类:让我们为name变量创建一个 setter(setter 功能齐全——这里没有问题):
class Human {
String name;
public void setName(String newName) {
name = newName;
}
}
请注意,我们将String newName传递给setName setter 方法 我们声明了一个新变量,并且可以随意命名它,因为它仅在包含 setName 方法的大括号 ({}) 内可见。请注意,设置器只有一行:
name = newName;
这里我们引入了一个名为newName的新变量,并将其分配给对象的现有名称变量。当我们最终谈论的是同一件事时,许多程序员可能会觉得引入一个新名称的变量很奇怪。也就是说,我们正在谈论Human类中的名称字段。这就是为什么 Java 的创造者想出了一种方法来方便地使用相同的变量名。换句话说,为什么一个变量有两个名称表示同一事物。换句话说,我们想做这样的事情:
class Human {
String name;
public void setName(String name) {
name = name;
}
}
但是这里我们遇到了一个问题。我们现在有两个同名的变量。一个String 名称属于Human类,而另一个String 名称属于其setName方法。因此,当您在 setter 中编写以下行时,JVM 将不知道您指的是哪个变量:
name = name;
Java 假定您指的是最接近的名称变量,即来自setName方法的名称变量: 


public class Solution {
public static void main(String[] args) {
Human human1 = new Human();
human1.setName("Vinny");
human1.print();
}
}
class Human {
String name;
public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
void print() {
System.out.println(name);
}
}
因此,这让我们避免引入新变量来表示相同的事物,从而使代码更清晰,并且不会因额外变量而混乱。
示例 2:将其用于显式构造函数调用
当您有(奇怪的是)多个构造函数并且您不希望新构造函数复制先前在不同构造函数中编写的初始化代码时,从另一个构造函数调用一个构造函数可能很有用。使困惑?它并不像看起来那么可怕。看看下面的代码。它有两个Human类的构造函数:
class Human {
int age;
int weight;
int height;
Human(int age, int weight) {
this.age = age;
this.weight = weight;
}
Human(int age, int weight, int height) {
// Call the constructor with two parameters
this(age, weight);
// and then initialize the missing variable
this.height = height;
}
}
在这里,我们首先提供了一个带有两个参数的构造函数:int age和int weight。假设它有两行代码:
this.age = age;
this.weight = weight;
稍后我们决定添加另一个具有三个参数的构造函数,将身高添加到现有的年龄和体重参数中。您可以像这样编写新的构造函数:
this.age = age;
this.weight = weight;
this.height = height;
但是,您可以使用this关键字显式调用带有两个参数的构造函数,而 不是在此构造函数中重复现有代码:
this(age, weight);
// and then initialize the missing variable:
this.height = height;
就好像我们在对三参数构造函数说:
- 调用另一个具有两个参数的构造函数
- 然后添加另一个变量。
GO TO FULL VERSION