在构造函数中使用 'this' 并在 Java 中使用其他方法 - 什么时候可以跳过它?

Using 'this' in constructor and other methods in Java - when is it OK to skip it?

我是 Java 的新手,如果这是一个愚蠢的问题,请原谅我。我试图在这个论坛上找到一个明确的答案,但没有快乐。

我知道 'this' 是什么。它知道它指的是一个实际实例,并有助于在定位变量时缩小上下文范围,但我发现尽管不使用 'this' 也可以毫无问题地执行代码短语。事实证明,这取决于您在声明方法时如何命名参数。正如您在下面看到的,代码 returns 'null' 如果我的参数命名与状态相同,我是 initialising/modifying.

这仅适用于声明变量的 class。你仍然必须在任何子 class 中使用 'this',如果它试图 access/modify 在其父 [=41] 中声明的变量=].

现在,这会被认为是不正确的吗?即使它看起来工作正常,也应该避免吗?

谢谢!

class Student {

  protected String name;
  protected int age;
  protected String course;

  public Student(String passName, int passAge, String course) {
    name = passName;
    age = passAge;
    course = course;   // here my parameter is named the same as the state and it will return 'null' unless we use 'this'

  }

  public void update(String newName, int newAge, String newCourse) {
    name = newName;
    age = newAge;
    course = newCourse;   // here I set the name of my parameter to be different and it works

  }

  public void display() {
    System.out.println("Name: " + name + "\n Age: " + age + "\n Course: " + course + "\n");
  }

  public static void main(String[] args) {

    Student s1 = new Student("John", 20, "Java 101");
    s1.display();

    s1.update("Johnny", 21, "Java 101");
    s1.display();
  }
}

输出:

Name: John
 Age: 20
 Course: null

Name: Johnny
 Age: 21
 Course: Java 101

如您所见,如果您为实例变量赋予与构造函数参数相同的名称,则赋值如

course = course; 

不初始化实例变量,因为构造函数的参数 course 是一个局部变量,隐藏了同名的实例变量。您正在将局部变量分配给它自己。

因此实例变量仍然是null.

你必须写

this.course = course;

为了让作业生效。

另一方面,如果实例变量的名称与构造函数参数的名称不同,您可以将构造函数的参数分配给实例变量,而无需使用 this 前缀。

两者

course = newCourse;

this.course = newCourse;

可以正常工作。

请注意,即使不是强制使用 this 前缀也有发现错误的优势。

比如你写错了

newCourse = course;

编译器不会报错,但是你的course实例变量不会被初始化。

另一方面,如果你写错了

this.newCourse = course;

编译器会给出编译错误,因为newCourse不是实例变量。

重要的是变量名。 Java 总是在最近的可用范围内使用变量,因此如果您使用同名参数,它将使用该参数。为避免这种情况,您需要使用 this 限定该字段。 这里(删除了不相关的代码):

  public Student(String course) {
    course = course;
  }

你把course的值赋给了参数course,所以字段course保持不变。例如,如果您这样做:

  public Student(final String course) {
    course = course;
  }

它不会编译,因为 final 关键字意味着您不允许为变量分配新值(在本例中,参数 course)。

所以需要使用this赋值给字段

  public Student(final String course) {
    this.course = course;
  }

使用 this 永远不会“不正确”,但您可能认为最好不要将参数命名为与字段相同的名称(如果您这样做,IDE 中会激活警告,以防止确切那个)。

我认为您应该阅读 official documantation 关于“this”关键字的内容。

Using this with a Field The most common reason for using the this keyword is because a field is shadowed by a method or constructor parameter.

For example, the Point class was written like this

public class Point {
    public int x = 0;
    public int y = 0;
        
    //constructor
    public Point(int a, int b) {
        x = a;
        y = b;
    }
}

but it could have been written like this:

public class Point {
    public int x = 0;
    public int y = 0;
        
    //constructor
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Each argument to the constructor shadows one of the object's fields — inside the constructor x is a local copy of the constructor's first argument. To refer to the Point field x, the constructor must use this.x.

关于你的问题:

Now, would this be considered incorrect and should it be avoided even though it seems to be working fine?

这取决于您的项目或团队中的代码风格。从技术上讲,这两种方式都是可行且正确的,使用 name = newName 更短,使用 this.name = name 更安全,避免出错。