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

时间:2010-03-09 17:57:04

标签: java oop this

我知道this指的是当前对象。但我不知道什么时候才能真正使用它。例如,如果我在某些方法中使用x而不是this.x,会有什么不同吗?可能x会引用所考虑方法的本地变量吗?我的意思是只在这种方法中看到的变量。

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

18 个答案:

答案 0 :(得分:312)

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

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

public class Foo
{
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

案例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();
    }
}

案例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
    }
}

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

答案 1 :(得分:66)

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;
    }
  }
}

答案 2 :(得分:44)

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

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

答案 3 :(得分:23)

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

答案 4 :(得分:15)

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

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}

答案 5 :(得分:10)

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();
    }

}

答案 6 :(得分:7)

除非你有重叠的变量名,否则它只是为了清楚你读代码时。

答案 7 :(得分:6)

有很多好的答案,但还有另一个非常小的理由将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;
        }
    }
}

使用任何现代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;
}
  1. 您知道foo是外部类Hello中声明的变量。
  2. 您知道getStringFromSomewhere()也是在外层类中声明的方法。
  3. 您知道bar属于World类,s是在该方法中声明的局部变量。
  4. 当然,每当你设计一些东西时,你都会创建规则。因此,在设计您的API或项目时,如果您的规则包括"如果有人用记事本打开所有这些源代码,他或她应该开枪自杀,"那么你完全没有做 this

答案 8 :(得分:4)

@William Brendel以很好的方式回答了三个不同的用例。

用例1:

this上的官方java文档页面提供了相同的用例。

  

在实例方法或构造函数中,这是对当前对象的引用 - 正在调用其方法或构造函数的对象。您可以使用此方法在实例方法或构造函数中引用当前对象的任何成员。

它包含两个例子:

将其与字段一起使用与构造函数一起使用

用例2:

此帖中未引用的其他用例:this可用于同步多线程应用程序中的当前对象以保护数据的关键部分。方法

synchronized(this){
    // Do some thing. 
}

用例3:

Builder模式的实现取决于使用this来返回修改后的对象。

参考这篇文章

Keeping builder in separate class (fluent interface)

答案 9 :(得分:2)

Google turned up a page on the Sun site that discusses this a bit.

你对这个变量是正确的; this确实可以用来区分方法变量和类字段。

    private int x;
    public void setX(int x) {
        this.x=x;
    }

然而,我真的讨厌这种惯例。赋予两个不同变量字面相同的名称是错误的一个秘诀。我更喜欢以下内容:

    private int x;
    public void setX(int newX) {
        x=newX;
    }

结果相同,但如果你真的打算引用x,那么当你意外引用x时就不会有错误。

至于使用方法,你对效果是对的;无论有没有,你都会得到相同的结果。你能用吗?当然。你应该用吗?由你决定,但考虑到我个人认为没有任何明确性的无意义冗长(除非代码中充满了静态导入语句),我不打算自己使用它。

答案 10 :(得分:2)

以下是在java中使用'this'关键字的方法:

  1. 使用this关键字来引用当前的类实例变量
  2. 使用this()调用当前的类构造函数
  3. 使用this关键字返回当前的类实例
  4. 使用this关键字作为方法参数
  5. https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

答案 11 :(得分:1)

当有两个变量时,一个实例变量和另一个同名的局部变量然后我们使用它。引用当前执行对象以避免名称之间的冲突。

答案 12 :(得分:1)

this是对当前对象的引用。它在构造函数中用于区分具有相同名称的本地和当前类变量。 e.g:

public class circle {
    int x;
    circle(int x){
        this.x =x;
        //class variable =local variable 
    }
} 

this也可用于从另一个构造函数调用一个构造函数。例如:

public class circle {
    int x;

    circle() { 
        this(1);
    }

    circle(int x) {
        this.x = x; 
    }
}

答案 13 :(得分:0)

this不会影响结果代码 - 它是编译时运算符,使用或不使用它生成的代码将是相同的。当您必须使用它时,取决于上下文。例如,你必须使用它,如你所说,当你有局部变量来影响类变量而你想要引用类变量而不是局部变量。

编辑:通过“结果代码将是相同的”我的意思当然,当局部范围中的某个变量不隐藏属于类的变量时。因此

class POJO {
   protected int i;

   public void modify() {
      i = 9;
   }

   public void thisModify() {
      this.i = 9;
   }
}

两种方法的结果代码都是一样的。不同之处在于,如果某个方法声明了具有相同名称的局部变量

  public void m() {
      int i;
      i = 9;  // i refers to variable in method's scope
      this.i = 9; // i refers to class variable
  }

答案 14 :(得分:0)

如果在某些方法中使用“x”而不是“this.x”,会有什么不同吗?

通常不是。但它有时会产生影响:

  class A {
     private int i;
     public A(int i) {
        this.i = i; // this.i can be used to disambiguate the i being referred to
     }
  }

如果我只使用“method()”,默认情况下它不会应用于当前对象吗?

是。但是如果需要,this.method()会澄清该对象是否进行了调用。

答案 15 :(得分:0)

关于William Brendel的帖子和dbconfessions问题,关于案例2 。这是一个例子:

public class Window {

  private Window parent;

  public Window (Window parent) {
    this.parent = parent;
  }

  public void addSubWindow() {
    Window child = new Window(this);
    list.add(child);
  }

  public void printInfo() {
    if (parent == null) {
      System.out.println("root");
    } else {
      System.out.println("child");
    }
  }

}

我在使用对象构建父子关系时看到了这种情况。但请注意,为简洁起见,它已经过简化。

答案 16 :(得分:0)

java中的“ This”关键字用于引用当前的类对象。

java中“ this”关键字有6种用法

  1. 访问课程级别变量:通常在本地变量和课程级别变量相同的情况下使用
  2. 访问类方法:这是默认行为,可以忽略
  3. 用于调用同一类的其他构造函数
  4. 使用“ this”关键字作为返回值:用于从方法中返回当前实例
  5. 将“ this”关键字作为自变量传递给方法:传递:用于将当前的类实例作为自变量
  6. 此关键字为构造方法的参数:用于将当前类实例作为参数传递

ref:https://stacktraceguru.com/java/this-keyword-in-java

答案 17 :(得分:-8)

确保使用当前对象的成员。某些应用程序可能会更改错误的对象成员值,因此应将其应用于该成员,以便使用正确的对象成员值。

如果您的对象与线程安全无关,则没有理由指定使用哪个对象成员的值。