跳到主要内容

Java this 关键字

提示
  1. this关键字基本概念:在Java中,this关键字用于方法或构造函数中引用当前对象,表示当前正在执行的对象的引用。
  2. this用于解决变量名称歧义:当类的字段(属性)和参数名称相同时,this关键字用于区分实例变量和参数,避免歧义。
  3. this在构造函数重载中的应用this关键字用于从一个构造函数中调用另一个构造函数,实现构造函数的重载,并简化代码。

this 关键字

在 Java 中,this 关键字用于在方法或构造函数中引用当前对象。例如,

class Main {
int instVar;

Main(int instVar){
this.instVar = instVar;
System.out.println("this 引用 = " + this);
}

public static void main(String[] args) {
Main obj = new Main(8);
System.out.println("对象引用 = " + obj);
}
}

输出

this 引用 = Main@23fc625e
对象引用 = Main@23fc625e

在上述示例中,我们创建了名为 objMain 类的对象。然后,我们打印了对象 obj 和类的 this 关键字的引用。

在这里,我们可以看到 objthis 的引用是相同的。这意味着 this 仅仅是对当前对象的引用。

this 关键字的用途

有多种情况下常用 this 关键字。

使用 this 消除变量名称的歧义

在 Java 中,不允许在一个作用域(类作用域或方法作用域)内声明两个或多个具有相同名称的变量。然而,实例变量和参数可以有相同的名称。例如,

class MyClass {
// 实例变量
int age;

// 参数
MyClass(int age){
age = age;
}
}

在上述程序中,实例变量和参数的名称都是:age。在这里,由于名称歧义,Java 编译器感到困惑。

在这种情况下,我们使用 this 关键字。例如,

首先,让我们看一个没有使用 this 关键字的例子:

class Main {

int age;
Main(int age){
age = age;
}

public static void main(String[] args) {
Main obj = new Main(8);
System.out.println("obj.age = " + obj.age);
}
}

输出

obj.age = 0

在上述示例中,我们将 8 作为值传递给了构造函数。然而,我们得到的输出是 0。这是因为 Java 编译器因实例变量和参数名称之间的歧义而感到困惑。

现在,让我们使用 this 关键字重写上述代码。

class Main {

int age;
Main(int age){
this.age = age;
}

public static void main(String[] args) {
Main obj = new Main(8);
System.out.println("obj.age = " + obj.age);
}
}

输出

obj.age = 8

现在,我们得到了预期的输出。这是因为当构造函数被调用时,构造函数内的 this 被替换为调用构造函数的对象 obj。因此 age 变量被赋值为 8

另外,如果参数名和实例变量名不同,编译器会自动添加 this 关键字。例如,代码:

class Main {
int age;

Main(int i) {
age = i;
}
}

等同于:

class Main {
int age;

Main(int i) {
this.age = i;
}
}

this 与 Getters 和 Setters

this 关键字的另一个常见用途是在类的 setter 和 getter 方法 中。例如:

class Main {
String name;

// setter 方法
void setName( String name ) {
this.name = name;
}

// getter 方法
String getName(){
return this.name;
}

public static void main( String[] args ) {
Main obj = new Main();

// 调用 setter 和 getter 方法
obj.setName("Toshiba");
System.out.println("obj.name: "+obj.getName());
}
}

输出

obj.name: Toshiba

在这里,我们使用了 this 关键字:

  • 在 setter 方法中赋值
  • 在 getter 方法中访问值

在构造函数重载中使用 this

在处理 构造函数重载 时,我们可能需要从一个构造函数中调用另一个构造函数。在这种情况下,我们不能显式调用构造函数。相反,我们必须使用 this 关键字。

在这里,我们使用了 this 关键字的不同形式。也就是说,this()。让我们看一个例子,

class Complex {

private int a, b;

// 有两个参数的构造函数
private Complex( int i, int j ){
this.a = i;
this.b = j;
}

// 有单个参数的构造函数
private Complex(int i){
// 调用有两个参数的构造函数
this(i, i);
}

// 无参数的构造函数
private Complex(){
// 调用有单个参数的构造函数
this(0);
}

@Override
public String toString(){
return this.a + " + " + this.b + "i";
}

public static void main( String[] args ) {

// 创建 Complex 类的对象
// 调用有两个参数的构造函数
Complex c1 = new Complex(2, 3);

// 调用有单个参数的构造函数
Complex c2 = new Complex(3);

// 调用无参数的构造函数
Complex c3 = new Complex();

// 打印对象
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
}
}

输出

2 + 3i
3 + 3i
0 + 0i

在上述示例中,我们使用了 this 关键字,

  • 在构造函数 Complex(int i) 中调用构造函数 Complex(int i, int j)
  • 在构造函数 Complex() 中调用构造函数 Complex(int i)

注意行,

System.out.println(c1);

这里,当我们打印对象 c1 时,对象被转换成字符串。在这个过程中,调用了 toString() 方法。由于我们在我们的类内覆盖了 toString() 方法,我们得到了根据该方法的输出。

使用 this() 的一个巨大优势是减少重复代码的数量。然而,在使用 this() 时我们应该始终小心。

这是因为从另一个构造函数调用构造函数增加了开销,而且是一个缓慢的过程。使用 this() 的另一个巨大优势是减少重复代码的数量。

注意

从一个构造函数调用另一个构造函数被称为显式构造函数调用。

将 this 作为参数传递

我们可以使用 this 关键字将当前对象作为参数传递给方法。例如,

class ThisExample {
// 声明变量
int x;
int y;

ThisExample(int x, int y) {
// 在构造函数内赋值变量
this.x = x;
this.y = y;

// 在调用 add() 之前的 x 和 y 的值
System.out.println("在传递 this 到 addTwo() 方法之前:");
System.out.println("x = " + this.x + ", y = " + this.y);

// 调用 add() 方法并传递 this 作为参数
add(this);

// 在调用 add() 之后的 x 和 y 的值
System.out.println("在传递 this 到 addTwo() 方法之后:");
System.out.println("x = " + this.x + ", y = " + this.y);
}

void add(ThisExample o){
o.x += 2;
o.y += 2;
}
}

class Main {
public static void main( String[] args ) {
ThisExample obj = new ThisExample(1, -2);
}
}

输出

在传递 thisaddTwo() 方法之前:
x = 1, y = -2
在传递 thisaddTwo() 方法之后:
x = 3, y = 0

在上述示例中,构造函数 ThisExample() 内,注意行,

add(this);

这里,我们通过将 this 作为参数传递调用 add() 方法。由于 this 关键字包含了类的对象 obj 的引用,我们可以在 add() 方法内改变 xy 的值。