【问题标题】:Java this.classProperty versus classProperty incase argument variable name clashes?Java this.classProperty 与 classProperty 以防参数变量名冲突?
【发布时间】:2012-04-27 05:57:14
【问题描述】:

如果第一个构造函数没有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 用这个

【问题讨论】:

    标签: java


    【解决方案1】:

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

    当然 - 此语句是无操作的:

    userId = userId;
    

    它只是将userId 参数的变量分配给它自己。它根本不涉及领域。在方法中,参数userId shadows 被称为userId 的字段 - 所以你必须明确地 说你想引用这个字段,这就是第二个版本:

    this.userId = userId;
    

    我希望任何现代 IDE 都会在第一个版本中突出显示无操作分配并发出警告。

    (顺便说一下,术语值得一提 - argument 是提供给方法的值;parameter 是声明为方法签名。同样,它是一个 field 而不是 property。)

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

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

    那么参数不会隐藏该字段,而标识符userId 仍然引用该字段。只需弄清楚标识符的含义 - 在您的第一个示例中,简单名称 userId 指的是参数,这就是导致问题的原因。

    编辑:来自section 6.4.1 of the JLS

    某些声明可能在其部分范围内被另一个同名声明所遮蔽,在这种情况下,不能使用简单名称来引用声明的实体。

    ...

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

    所以在这种情况下 d 将是形参 userId 的声明,d 的范围是构造函数 - 因此通过构造函数,参数会隐藏字段。

    【讨论】:

    • 谢谢,但如果我使用 public User(int Id){ userId = Id;},它会更新类属性。
    • @talktopk:是的,因为在这种情况下,参数不会影响字段。
    • 所以我猜有一个偏好,以防发生冲突。
    • @JonSkeet 我正要评论 Sun/Oracle 使用隐藏与阴影,但您已经编辑了答案:)
    • @milkplusvellocet:是的,我之前没有仔细看。现在也变得模糊了……
    【解决方案2】:

    这是因为shadowing

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多