如果没有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
答案 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
关键字的输出的原因。