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

问题描述 投票:233回答:17

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

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

java oop this
17个回答
314
投票

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过去常常强调一个实例变量被引用(不需要消除歧义),但在我看来这是一种罕见的情况。


2
投票

Keeping builder in separate class (fluent interface)

你对这个变量是正确的; 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

至于在方法中使用它,你的效果是对的;无论有没有,你都会得到相同的结果。你能用吗?当然。你应该用吗?由你决定,但鉴于我个人认为这是毫无意义的冗长,不会增加任何清晰度(除非代码充满了静态导入语句),我并不倾向于自己使用它。


2
投票

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

  1. 使用x关键字来引用当前的类实例变量
  2. 使用this来调用当前的类构造函数
  3. 使用this()关键字返回当前的类实例
  4. 使用this关键字作为方法参数

this


1
投票

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


1
投票

https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html是对当前对象的引用。它在构造函数中用于区分具有相同名称的本地和当前类变量。例如。:

this

public class circle { int x; circle(int x){ this.x =x; //class variable =local variable } } 也可用于从另一个构造函数调用一个构造函数。例如。:

this

0
投票

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

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

public class circle {
    int x;

    circle() { 
        this(1);
    }

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

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

是。但是如果需要的话, class A { private int i; public A(int i) { this.i = i; // this.i can be used to disambiguate the i being referred to } } 澄清了这个对象的调用。


0
投票

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

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

this

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

class POJO {
   protected int i;

   public void modify() {
      i = 9;
   }

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

0
投票

关于 public void m() { int i; i = 9; // i refers to variable in method's scope this.i = 9; // i refers to class variable } 的帖子和William Brendel问题,关于案例2.这是一个例子:

dbconfessions

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


-8
投票

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

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


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

44
投票

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

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


23
投票

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


15
投票

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

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

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

}

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是在该方法中声明的局部变量。

当然,无论何时设计某些东西,都可以创建规则。因此,在设计您的API或项目时,如果您的规则包括“如果有人用记事本打开所有这些源代码,他或她应该射击他/她自己”,那么你完全没有这样做。


4
投票

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

用例1:

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

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

它包括两个例子:

将其与Field一起使用并将其与构造函数一起使用

用例2:

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

this

用例3:

synchronized(this){ // Do some thing. } 模式的实现取决于使用Builder返回修改后的对象。

请参阅这篇文章

this

© www.soinside.com 2019 - 2024. All rights reserved.