什么时候应该在课堂上使用"this"?

Rom*_*man 245 java oop this

我知道这this是指当前的对象.但我不知道什么时候才能真正使用它.例如,如果我使用x而不是this.x在某些方法中,会有什么区别吗?可能x会引用一个考虑方法的局部变量?我的意思是仅在此方法中看到的变量.

怎么样this.method()?我可以用吗?我应该用它吗?如果我只是使用method(),默认情况下它不会应用于当前对象吗?

Wil*_*del 325

this关键字主要用于三种情况.第一个也是最常见的是在setter方法中消除变量引用的歧义.第二种是当需要将当前类实例作为参数传递给另一个对象的方法时.第三种方法是从构造函数中调用备用构造函数.

案例1:使用this来消除歧义变量引用.在Java setter方法中,我们通常传入一个与我们试图设置的私有成员变量同名的参数.然后我们将参数赋值xthis.x.这清楚地表明您将参数"name"的值赋给实例变量"name".

public class Foo
{
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

情况2:使用this作为参数传递给另一个对象.

public class Foo
{
    public String useBarMethod() {
        Bar theBar = new Bar();
        return theBar.barMethod(this);
    }

    public String getName() {
        return "Foo";
    }
}

public class Bar
{
    public void barMethod(Foo obj) {
        obj.getName();
    }
}
Run Code Online (Sandbox Code Playgroud)

案例3:使用this调用备用构造.在评论中,trinithis正确地指出了另一种常见用法this.如果在单个类中有多个构造函数,则可以使用它this(arg0, arg1, ...)来调用您选择的另一个构造函数,前提是您在构造函数的第一行中执行此操作.

class Foo
{
    public Foo() {
        this("Some default value for bar");

        //optional other lines
    }

    public Foo(String bar) {
        // Do something with bar
    }
}
Run Code Online (Sandbox Code Playgroud)

我还看到this过去曾经强调过引用一个实例变量这一事实(不需要消除歧义),但在我看来这是一种罕见的情况.

  • +1提及你也可以传递_this_作为参数._this_不仅用于范围消歧. (17认同)
  • 当然在构造函数中也有`this(arg1,arg2,...)`. (12认同)
  • @Hazior:我倾向于写一个简短的答案,然后随着时间的推移添加它.有时与其他人的答案重叠,有时则不然.在我最新编辑的情况下,trinithis指出了我忘记的另一个常用的"this",所以我把它添加到我的答案中.我没有看到任何错误,因为最终结果是一个更好的答案,这正是SO的目的.我也试图尽可能地给予信任,正如我在trinithis的情况下所做的那样. (11认同)
  • 你有案例1和案例3的例子.你能举个案例2的例子,其中当前的类实例被用作另一个类的方法的参数吗? (4认同)
  • @AStar在我多年来一直使用的大多数Java代码库中,只有在真正需要消歧的情况下才会使用`this`,就像我上面的setter示例一样.编码风格和"最佳实践"可以根据您的要求而有很大差异,当然,但总的来说,我建议选择合理的模式并坚持使用它们.一致性,即使只是在单个代码库内部,也可以实现可读性和可维护性. (4认同)
  • 即使没有冲突,最好的做法是使用“this.”吗? (2认同)

Chr*_*bek 68

第二个重要用途this(除了隐藏了一个局部变量,就像许多答案已经说过的那样)是从嵌套的非静态类访问外部实例时:

public class Outer {
  protected int a;

  public class Inner {
    protected int a;

    public int foo(){
      return Outer.this.a;
    }

    public Outer getOuter(){
      return Outer.this;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


fro*_*die 45

当只有this一个具有相同名称的重叠局部变量时,您只需要使用- 并且大多数人只使用它.(例如,Setter方法.)

当然,使用的另一个好理由this是它会导致在IDE中弹出intellisense :)

  • 但是,您必须在查找后退格它。编程很累! (3认同)

Ada*_*son 23

唯一需要使用this.限定符的是当前作用域中的另一个变量共享同一个名称并且您想要引用实例成员(如William描述).除此之外,x和之间的行为没有区别this.x.

  • 如果你有重复的名字,你的一个变量应该被重命名,因为它几乎肯定是不正确的.或者至少,可以更好地命名. (3认同)
  • @Chad:这是Java setter方法中的常见做法.但是,在setter方法之外,您的语句通常都有. (3认同)
  • 您可能希望使用`this.x`来更清楚地读取代码,代码的可维护性/可读性也是您应该考虑的因素... (2认同)
  • @Blair:阅读你的答案清楚地表明你不喜欢这种做法在setter方法中,但很多人都这样做(我将自己列入该列表中).如果我有一个取值的setter方法,那么传入的值显然是"new"值,因此在变量名称中添加"new"似乎会给公共API增加不必要的冗余. (2认同)

小智 15

从另一个构造函数调用时,"this"也很有用:

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)


Kie*_*xon 11

this 在构建器模式中很有用.

public class User {

    private String firstName;
    private String surname;

    public User(Builder builder){
        firstName = builder.firstName;
        surname = builder.surname;
    }

    public String getFirstName(){
        return firstName;
    }

    public String getSurname(){
        return surname;
    }

    public static class Builder {
        private String firstName;
        private String surname;

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setSurname(String surname) {
            this.surname = surname;
            return this;
        }

        public User build(){
            return new User(this);
        }

    }

    public static void main(String[] args) {
        User.Builder builder = new User.Builder();
        User user = builder.setFirstName("John").setSurname("Doe").build();
    }

}
Run Code Online (Sandbox Code Playgroud)


Chi*_*omb 7

除非你有重叠的变量名称,否则当你阅读代码时,它只是为了清晰起见.

  • @AxeEffect我知道这确实很旧,但是...`this`不会使代码更难阅读。 (3认同)
  • 当你经常看到不必要的“this”关键字时,它只是样板代码,使代码更难阅读。 (2认同)

Jai*_*Jai 7

有很多好的答案,但还有另一个非常小的理由可以放在this任何地方.如果您尝试从普通文本编辑器(例如记事本等)打开源代码,使用this将使阅读更加清晰.

想象一下:

public class Hello {
    private String foo;

    // Some 10k lines of codes

    private String getStringFromSomewhere() {
        // ....
    }

    // More codes

    public class World {
        private String bar;

        // Another 10k lines of codes

        public void doSomething() {
            // More codes
            foo = "FOO";
            // More codes
            String s = getStringFromSomewhere();
            // More codes
            bar = s;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用任何现代IDE都可以清楚地看到这一点,但这将是用常规文本编辑器阅读的完全噩梦.

foo使用编辑器的"查找"功能之前,您将很难找到驻留的位置.然后你会getStringFromSomewhere()因同样的原因尖叫.最后,在你忘记了什么之后s,那bar = s会给你最后的打击.

比较一下:

public void doSomething() {
    // More codes
    Hello.this.foo = "FOO";
    // More codes
    String s = Hello.this.getStringFromSomewhere();
    // More codes
    this.bar = s;
}
Run Code Online (Sandbox Code Playgroud)
  1. 你知道foo是在外部类中声明的变量Hello.
  2. 您知道getStringFromSomewhere()也是在外部类中声明的方法.
  3. 您知道它bar属于Worldclass,并且s是在该方法中声明的局部变量.

当然,无论何时设计某些东西,都可以创建规则.所以在设计你的API或项目,如果你的规则包括"如果有人打开所有这些源代码中有一个记事本,他或她应该拍他/她的头,"那么你是完全罚款不去做这个.