Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用';这';在Java的构造函数和其他方法中-什么时候可以跳过它?_Java_This - Fatal编程技术网

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

使用';这';在Java的构造函数和其他方法中-什么时候可以跳过它?,java,this,Java,This,我是Java新手,如果这是个愚蠢的问题,请原谅我。我试图在这个论坛上找到一个明确的答案,但毫无乐趣 我知道这是什么。它知道它引用了一个实际的实例,并且在针对一个变量时有助于缩小上下文范围,但是我发现,尽管没有使用“this”短语,执行代码时也可能没有任何问题。事实证明,这取决于声明方法时如何命名参数。正如您在下面看到的,如果我的参数命名为与我正在初始化/修改的状态相同,代码将返回'null' 这仅适用于声明变量的类。如果子类试图访问/修改其父类中声明的变量,则仍必须在任何子类中使用'this'

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

我知道这是什么。它知道它引用了一个实际的实例,并且在针对一个变量时有助于缩小上下文范围,但是我发现,尽管没有使用“this”短语,执行代码时也可能没有任何问题。事实证明,这取决于声明方法时如何命名参数。正如您在下面看到的,如果我的参数命名为与我正在初始化/修改的状态相同,代码将返回'null'

这仅适用于声明变量的类。如果子类试图访问/修改其父类中声明的变量,则仍必须在任何子类中使用'this'

现在,这会被认为是不正确的吗?即使它看起来运行良好,也应该避免吗

谢谢

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
前缀

两者

那就行了

请注意,使用
this
前缀(即使不是强制性的)也有发现bug的优势

例如,如果你写错了

newCourse = course;
this.newCourse = course;
编译器不会抱怨,但是您的
课程
实例变量不会初始化

另一方面,如果你写错了

newCourse = course;
this.newCourse = course;

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

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

您将
课程
的值分配给参数
课程
,因此
课程
字段保持不变。例如,如果您这样做:

  public Student(final String course) {
    course = course;
  }
它不会编译,因为
final
关键字意味着不允许为变量分配新值(在本例中,参数
course

因此,您需要使用
来分配给字段

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

使用<代码> < <代码>永远不会是“不正确的”,但是您可能认为不要将参数命名为与字段相同的好实践(并且如果在IDE中有警告要激活,以准确地防止)。

< P>我想您应该阅读“这个”关键字。

对字段使用this使用this关键字的最常见原因是字段被方法或构造函数隐藏 参数

例如,Point类是这样编写的

public class Point {
    public int x = 0;
    public int y = 0;
        
    //constructor
    public Point(int a, int b) {
        x = a;
        y = b;
    }
}
但它可能是这样写的:

public class Point {
    public int x = 0;
    public int y = 0;
        
    //constructor
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
构造函数的每个参数都会隐藏对象的一个字段- 在构造函数x内部是构造函数的第一个 论点要引用点字段x,构造函数必须使用 这个

关于你的问题:

现在,这会被认为是不正确的,甚至应该避免吗 虽然它看起来很好用


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

“现在,这会被认为是不正确的,即使它看起来工作正常,也应该避免吗?”你说的“这”是什么意思?“在这里,我的参数的名称与状态相同,它将返回'null'”它不返回任何内容:您只是将参数分配给它自己,而不是对字段执行任何操作。您的问题的答案是使用“this”"; 在了解了基本知识之后,也许可以使用Lombok来实现快速getter/setter/constructor/toString/EqualsAndHashCode……为什么不将参数命名为字段是一种好的做法;但这就是AllArgsConstructor和Setter的工作方式嗨,谢谢你的评论。我知道为什么
course=course
不起作用,以及为什么在这种特殊情况下需要
this
。我的主要问题是跳过“this”是否合适,如果你给你的角色起不同的名字。如果变量的顺序相反,这是发现bug的一个要点。从现在开始,就是这样汉克斯!你的最后一段回答了我的问题。嗨!如果这篇文章回答了你的问题,你能接受它吗(只是为了帮助其他人将来如何阅读这个话题)?或者你可以接受任何其他答案,如果你认为它更适合你。
public class Point {
    public int x = 0;
    public int y = 0;
        
    //constructor
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}