Java this 关键字
- this关键字基本概念:在Java中,
this
关键字用于方法或构造函数中引用当前对象,表示当前正在执行的对象的引用。 - this用于解决变量名称歧义:当类的字段(属性)和参数名称相同时,
this
关键字用于区分实例变量和参数,避免歧义。 - 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
在上述示例中,我们创建了名为 obj
的 Main
类的对象。然后,我们打印了对象 obj
和类的 this 关键字的引用。
在这里,我们可以看到 obj
和 this
的引用是相同的。这意味着 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);
}
}
输出:
在传递 this 到 addTwo() 方法之前:
x = 1, y = -2
在传递 this 到 addTwo() 方法之后:
x = 3, y = 0
在上述示例中,构造函数 ThisExample()
内,注意行,
add(this);
这里,我们通过将 this 作为参数传递调用 add()
方法。由于 this 关键字包含了类的对象 obj
的引用,我们可以在 add()
方法内改变 x
和 y
的值。