【问题标题】:Java - when to use 'this' keyword [duplicate]Java - 何时使用'this'关键字[重复]
【发布时间】:2011-01-26 14:37:04
【问题描述】:

在 Java 中使用 this 关键字的最佳做法是什么?例如,我有以下课程:

class Foo {
    Bar bar;

    public Foo(Bar bar) {
         this.bar = bar;
    }
}

这很好,但是如果我将构造函数中的语句更改为,Java 足够聪明,可以知道会发生什么

 bar = bar;

那么为什么要使用this 关键字呢? (我意识到在某些情况下,完全有必要使用它,我只是要求这样的情况)。实际上,我倾向于纯粹为了可读性而使用关键字,但常见的做法是什么?例如,在整个商店中使用它会使我的代码看起来有点混乱

boolean baz;
int someIndex = 5;
this.baz = this.bar.getSomeNumber() == this.someBarArray[this.someIndex].getSomeNumber();

显然代码很差,但它说明了我的示例。在这些情况下是否仅取决于个人喜好?

【问题讨论】:

  • 2天前发过同样的问题:stackoverflow.com/questions/2411270/… 顺便还有更多骗子:google.com/…
  • 我的错,我使用 SO 搜索进行了(显然非常)快速搜索,但没有找到任何东西......
  • 正如其他人指出的那样,您正在对上面的 self (参数)进行分配。但我的经验法则是使用this,当它使程序更可读。如果您对成员变量使用某种命名约定(例如_barmBar),那么写this._bar 只是额外的噪音,恕我直言。
  • 真正的问题(对我来说)是为什么人们在地球上对方法参数和成员变量使用相同的名称?我无法忍受这种做法,因为它只会带来混乱的机会。不幸的是(对我来说)这是非常流行的,大多数自动生成代码的框架都这样做:/ Grr...
  • 如果你不在局部变量中使用相同的标识符,this 在你的第一种情况下可以省略。而且,至于其他情况,我认为正确性和可读性是美。

标签: java coding-style this


【解决方案1】:

但是如果我将构造函数中的语句更改为,Java 足够聪明,可以知道会发生什么

  bar = bar;

错误!它可以编译,但并没有按照您的想法执行!

至于什么时候用,很多都是个人喜好。我喜欢在我的公共方法中使用this,即使它是不必要的,因为这是接口发生的地方,并且很高兴断言什么是我的,什么不是。

作为参考,您可以查看有关 this.subject 的 Oracle 的 Java 教程;-)

http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

【讨论】:

  • 这就是为什么我喜欢将所有参数变量标记为final。
  • 是的,它只是将构造函数中的变量 bar 重新分配给它自己。这是因为 bar 已经在作用域中定义,它覆盖了来自 Bar bar 的那个。
【解决方案2】:

当你有一个与字段同名的参数时,你应该使用它,否则你会遇到问题。它会编译,但不一定会做你想做的事。

至于其他任何地方,除非为了可读性需要,否则不要使用它。如果在任何地方都使用它,那么 20% 的代码将包含单词“this”!

【讨论】:

  • 尽管有争议的是,明确的this 关键字无处不在。像 Python 和 Rust 这样的语言实际上需要它 (self),而且我从未将这种明确性视为否定。
  • 精彩的回答,简短,简洁,中肯
【解决方案3】:

this 关键字是指调用某个方法的类的对象。
例如:

public class Xyz {  
    public Xyz(Abc ob)
    {
        ob.show();
    }
}

public class Abc {
    int a = 10;

    public Abc()
    {
        new Xyz(this);
    }

    public void show()
    {
        System.out.println("Value of a " + a);
    }

    public static void main(String s[])
    {
        new Abc();
    }
}

Abc() 中,我们调用Xyz(),它需要Abc 类的对象。所以我们可以传递this 而不是新的Abc(),因为如果我们在这里传递新的Abc(),它将再次调用自己然后再次。

我们也用它来区分类的变量和方法的局部变量。例如

class Abc {
    int a;

    void setValue(int a)
    {
        this.a = a;
    }
}

这里的this.a 是指Abc 类的变量a。因此与您使用新的Abc().a; 具有相同的效果。

所以你可以说this 指的是当前类的对象。

【讨论】:

    【解决方案4】:

    其实

    baz = baz
    

    将发出此警告

    对变量 baz 的赋值没有 效果

    所以您认为是错误的,本地范围会覆盖类属性,因此您必须明确使用 this 关键字将变量分配给类属性。

    否则,分配给赋值的变量只是作为参数传递的变量,而类一将被忽略。这就是this 有用的原因,这不是可读性的事实,而是明确决定您在说哪个baz 的事实。

    我会说

    使用this 不使用它会导致歧义(或编译器警告,这更重要),否则就离开它。因为它的目的正是在默认假设(首先检查局部变量,然后检查类属性)不够时解决歧义。

    【讨论】:

      【解决方案5】:

      显式构造函数调用中通常使用this关键字。您可以从documentation 看到一个示例。

      public class Rectangle {
          private int x, y;
          private int width, height;
      
          public Rectangle() {
              this(0, 0, 1, 1);
          }
          public Rectangle(int width, int height) {
              this(0, 0, width, height);
          }
          public Rectangle(int x, int y, int width, int height) {
              this.x = x;
              this.y = y;
              this.width = width;
              this.height = height;
          }
          ...
      }
      

      【讨论】:

        【解决方案6】:
        public Foo(Bar bar) {
             this.bar = bar;
        }
        

        不一样

        public Foo(Bar bar) {
             bar = bar;
        }
        

        在第二种情况下,范围内的栏是参数,因此您将其分配给自身。 this.bar 仍然是 null

        【讨论】:

          【解决方案7】:

          这是个人喜好 - 选择一种风格并坚持下去。我个人使用this,但其他人认为它是多余的。

          【讨论】:

            【解决方案8】:

            根据约定,您可以使用它来提高可读性。它强调它是一个对象变量。

            我还喜欢使用与变量同名的 setter 参数(在方法签名中看起来更好)。在这种情况下,您需要 this

            【讨论】:

              【解决方案9】:

              我总是尝试在本地类对象上使用 this 关键字。

              我用它来直观地提醒我一个对象是静态对象还是类对象。

              它帮助我和编译器区分方法参数和本地类对象。

              public void setValue(int value){
                this.value = value;
              }
              

              它可以帮助我直观地提醒我在内部/嵌套/匿名类中是否存在这样的本地对象,以将其与封装类对象区分开来。因为如果没有this前缀,我的约定会提醒我是封装类的对象

              public class Hello{
                public int value = 0;
                public boolean modal = false;
              
                public class Hellee{
                  public int value = 1;
                  public getValue(){
                    if (modal)
                      return 0;
                    return this.value;
                  }
                }
              }
              

              【讨论】:

                【解决方案10】:
                void set(int real)
                {
                    this.real = real;
                }
                

                这里this是有实例变量和局部变量相同时使用的关键字。
                this 的另一个用途是构造函数重载。它可以在重载的构造函数中调用构造函数。

                【讨论】:

                  【解决方案11】:

                  个人喜好,但我只用它来解决歧义,我想在极少数情况下明确分配的变量是一个字段。在某些项目中,人们在每个字段引用上都使用“this.field”。我发现这种做法在视觉上会分散注意力到令人讨厌的程度,但你应该准备好偶尔看到这样的代码。

                  我暗地里认为,对于编写 500 个行类且其中包含 275 个“this”关键字的人来说,地狱里有一个特殊的地方,但是这种风格在一些开源项目中可以找到,所以我猜每个人都有自己的风格。

                  【讨论】:

                  • +1 如果发现在任何地方都使用 this.* 非常烦人。如果您使用的是现代 IDE,并且正确设计类,您将永远不会遇到必须弄清楚什么是引用的变量是(属性、局部变量等)
                  【解决方案12】:

                  将其用于克隆对象(通过复制构造函数传递自身的引用)。

                  对于继承 Cloneable 的对象很有用。

                  public Foo implements Cloneable {
                    private String bar;
                  
                    public Foo(Foo who) {
                      bar = who.bar;
                    }
                  
                    public Object getClone() {
                      return new Foo(this);  //Return new copy of self.
                    }
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 2010-10-25
                    • 2010-10-09
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-04-15
                    • 2019-11-18
                    • 2011-10-10
                    • 2020-05-01
                    相关资源
                    最近更新 更多