原文: https://www.programiz.com/java-programming/this-keyword

在本文中,我们将通过示例了解 Java 中的this关键字,以及如何以及在何处使用它们。

this关键字

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

  1. class Main {
  2. int instVar;
  3. Main(int instVar){
  4. this.instVar = instVar;
  5. System.out.println("this reference = " + this);
  6. }
  7. public static void main(String[] args) {
  8. Main obj = new Main(8);
  9. System.out.println("object reference = " + obj);
  10. }
  11. }

输出

  1. this reference = com.ThisAndThat.MyClass@74a14482
  2. object reference = com.ThisAndThat.MyClass@74a14482

在上面的示例中,我们创建了一个名为Main的对象obj。 然后,我们打印类的对象的引用objthis

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


使用this关键字

在许多情况下,通常都使用this关键字。

使用this作为歧义变量名

在 Java 中,不允许在范围(类范围或方法范围)内声明两个或多个具有相同名称的变量。 但是,实例变量和参数可能具有相同的名称。 例如,

  1. class MyClass {
  2. // instance variable
  3. int age;
  4. // parameter
  5. MyClass(int age){
  6. age = age;
  7. }
  8. }

在上面的程序中,实例变量和参数具有相同的名称:age。 在这里,由于名称不明确,Java 编译器感到困惑。

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

首先,让我们看一个不使用this关键字的示例:

  1. class Main {
  2. int age;
  3. Main(int age){
  4. age = age;
  5. }
  6. public static void main(String[] args) {
  7. Main obj = new Main(8);
  8. System.out.println("obj.age = " + obj.age);
  9. }
  10. }

输出

  1. mc.age = 0

在上面的示例中,我们将8作为值传递给了构造器。 但是,我们得到0作为输出。 这是因为 Java 编译器由于实例变量和参数之间的名称不明确而感到困惑。

现在,让我们使用this关键字覆盖上面的代码。

  1. class Main {
  2. int age;
  3. Main(int age){
  4. this.age = age;
  5. }
  6. public static void main(String[] args) {
  7. Main obj = new Main(8);
  8. System.out.println("obj.age = " + obj.age);
  9. }
  10. }

输出

  1. obj.age = 8

现在,我们正在获得预期的输出。 这是因为调用构造器时,构造器内部的this被调用了构造器的对象obj代替。 因此,将age变量分配给值8

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

  1. class Main {
  2. int age;
  3. Main(int i) {
  4. age = i;
  5. }
  6. }

等效于:

  1. class Main {
  2. int age;
  3. Main(int i) {
  4. this.age = i;
  5. }
  6. }

this和获取器和设置器

this关键字的另一种常见用法是在类的获取器和设置器中。 例如:

  1. class Main {
  2. String name;
  3. // setter method
  4. void setName( String name ) {
  5. this.name = name;
  6. }
  7. // getter method
  8. String getName(){
  9. return this.name;
  10. }
  11. public static void main( String[] args ) {
  12. Main obj = new Main();
  13. // calling the setter and the getter method
  14. obj.setName("Toshiba");
  15. System.out.println("obj.name: "+obj.getName());
  16. }
  17. }

输出

  1. obj.name: Toshiba

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

  • 在设置器方法中赋值
  • 在获取器方法中访问值

在构造器重载中使用它

在使用构造器重载的同时,我们可能不得不从另一个构造器调用一个构造器。 在这种情况下,我们不能显式调用构造器。 相反,我们必须使用this关键字。

在这里,我们使用this关键字的另一种形式。 即,this()。 让我们举个例子

  1. class Complex {
  2. private int a, b;
  3. // constructor with 2 parameters
  4. private Complex( int i, int j ){
  5. this.a = i;
  6. this.b = j;
  7. }
  8. // constructor with single parameter
  9. private Complex(int i){
  10. // invokes the constructor with 2 parameters
  11. this(i, i);
  12. }
  13. // constructor with no parameter
  14. private Complex(){
  15. // invokes the constructor with single parameter
  16. this(0);
  17. }
  18. @Override
  19. public String toString(){
  20. return this.a + " + " + this.b + "i";
  21. }
  22. public static void main( String[] args ) {
  23. // creating object of Complex class
  24. // calls the constructor with 2 parameters
  25. Complex c1 = new Complex(2, 3);
  26. // calls the constructor with a single parameter
  27. Complex c2 = new Complex(3);
  28. // calls the constructor with no parameters
  29. Complex c3 = new Complex();
  30. // print objects
  31. System.out.println(c1);
  32. System.out.println(c2);
  33. System.out.println(c3);
  34. }
  35. }

输出

  1. 2 + 3i
  2. 3 + 3i
  3. 0 + 0i

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

  • 从构造器Complex(int i)调用构造器Complex(int i, int j)
  • 从构造器Complex()调用构造器Complex(int i)

注意这一行,

  1. System.out.println(c1);

在这里,当我们打印对象c1时,该对象将转换为字符串。 在此过程中,将调用toString()。 由于我们在类内部覆盖了toString()方法,因此根据该方法获得输出。

this()的巨大优势之一是减少重复代码的数量。 但是,在使用this()时应始终小心。

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

注意:从另一个构造器调用一个构造器称为显式构造器调用。


作为参数传递

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

  1. class ThisExample {
  2. // declare variables
  3. int x;
  4. int y;
  5. ThisExample(int x, int y) {
  6. // assign values of variables inside constructor
  7. this.x = x;
  8. this.y = y;
  9. // value of x and y before calling add()
  10. System.out.println("Before passing this to addTwo() method:");
  11. System.out.println("x = " + this.x + ", y = " + this.y);
  12. // call the add() method passing this as argument
  13. add(this);
  14. // value of x and y after calling add()
  15. System.out.println("After passing this to addTwo() method:");
  16. System.out.println("x = " + this.x + ", y = " + this.y);
  17. }
  18. void add(ThisExample o){
  19. o.x += 2;
  20. o.y += 2;
  21. }
  22. }
  23. class Main {
  24. public static void main( String[] args ) {
  25. ThisExample obj = new ThisExample(1, -2);
  26. }
  27. }

输出

  1. Before passing this to addTwo() method:
  2. x = 1, y = -2
  3. After passing this to addTwo() method:
  4. x = 3, y = 0

在上面的示例中,在构造器ThisExample()中,请注意以下行:

  1. add(this);

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