Java this.class属性vs class属性incase参数变量名称冲突?

时间:2012-04-15 18:58:21

标签: java

如果没有this的第一个构造函数,有人可以解释输出0吗?

如果参数变量名与类属性名相同,并且我在方法中使用该属性。 java解释了什么"类属性"或"参数变量" ?

没有this

 public User(int userId){
    userId = userId;

 }

使用this

 public User(int userId){
    this.userId = userId;

 }


 public void PrintUserId(){
    System.out.println(this.userId);
}

 User firstUser = new User(123);
 firstUser.PrintUserId(); 

// 0没有这个

// 123 with this

2 个答案:

答案 0 :(得分:6)

  

如果没有第一个构造函数,有人可以解释输出0吗?

当然 - 这句话是无操作的:

userId = userId;

它只是将userId参数的变量赋给自身。它完全没有碰到这个领域。在方法中,参数userId 阴影名为userId的字段 - 因此您必须明确表示您要引用该字段,这是第二个版本的作用:

this.userId = userId;

我希望任何现代IDE都能在第一个版本中突出显示no-op赋值并带有警告。

(顺便说一下,术语是值得清楚的 - 参数是提供给方法的值; 参数是声明为部分的变量方法签名。同样,它是字段而不是属性。)

编辑:如果参数具有不同的名称,例如

public User(int id) {
    userId = id;
}

然后参数遮蔽该字段,标识符userId仍然引用该字段。所有这一切都要弄清楚标识符的含义是什么 - 在第一个例子中,简单名称userId引用了参数,这就是导致问题的原因。

编辑:来自section 6.4.1 of the JLS

  

某些声明可能会在其作用域的一部分中被另一个同名声明所遮蔽,在这种情况下,简单名称不能用于引用声明的实体。

     

...

     

在整个d范围内,名为n shadows的字段或形式参数的声明d,名称为n的任何其他变量的声明,这些变量在d出现的范围内。

所以在这种情况下,d将是形式参数userId的声明,d的范围是构造函数 - 所以在构造函数中,参数会遮蔽该字段。

答案 1 :(得分:4)

这是因为shadowing

您没有将参数值userId分配给成员变量,因为它被遮蔽了。因为int成员变量初始化为0,这就是为什么你看到没有this关键字的输出的原因。