Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该在什么时候使用;这";在课堂上?_Java_Oop_This - Fatal编程技术网

Java 我应该在什么时候使用;这";在课堂上?

Java 我应该在什么时候使用;这";在课堂上?,java,oop,this,Java,Oop,This,我知道这个指的是当前对象。但我不知道什么时候我真的需要使用它。例如,如果我在某些方法中使用x而不是this.x,会有什么区别吗?可能是x将引用所考虑方法的局部变量?我指的是只有在这种方法中才能看到的变量 那么这个.method()呢?我能用它吗?我应该用它吗。如果我只使用method(),默认情况下它不会应用于当前对象吗?此关键字主要用于三种情况。第一个也是最常见的是setter方法来消除变量引用的歧义。第二种是当需要将当前类实例作为参数传递给另一个对象的方法时。第三种方法是从构造函数中调用备用

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


那么
这个.method()
呢?我能用它吗?我应该用它吗。如果我只使用
method()
,默认情况下它不会应用于当前对象吗?

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

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

        //optional other lines
    }

    public Foo(String bar) {
        // Do something with bar
    }
}
案例1:使用
消除变量引用的歧义。在Java setter方法中,我们通常传入一个与试图设置的私有成员变量同名的参数。然后我们将参数
x
分配给
this.x
。这表明您正在将参数“name”的值指定给实例变量“name”

案例2:使用
作为传递给另一个对象的参数

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
调用备用构造函数。在评论中,正确地指出了此
的另一个常见用法。当一个类有多个构造函数时,您可以使用
this(arg0,arg1,…)
调用您选择的另一个构造函数,前提是在构造函数的第一行这样做

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

        //optional other lines
    }

    public Foo(String bar) {
        // Do something with bar
    }
}

我也看到了
这个
用来强调引用实例变量的事实(无需消除歧义),但在我看来这是一种罕见的情况。

除非您有重叠的变量名,当您阅读代码时,这只是为了清楚起见。

唯一需要使用
这个限定符。
限定符是当前范围内的另一个变量共享相同的名称,并且您希望引用实例成员(如William所述)。除此之外,
x
this.x
在某些方法中使用“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()
说明调用是由该对象进行的。

您只需要使用
this
——大多数人只需要使用它——当存在同名的重叠局部变量时。(例如,Setter方法。)


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

这个
不会影响生成的代码-它是编译时间操作符,使用或不使用它生成的代码都是相同的。当您必须使用它时,这取决于上下文。例如,您必须使用它,正如您所说的,当您有局部变量时,它会隐藏类变量,并且您希望引用类变量而不是局部变量

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

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
  }

关于变量,你是对的
这确实可以用来区分方法变量和类字段。

私人INTX;
公共无效集合x(整数x){
这个.x=x;
}

然而,我真的很讨厌那个惯例。给两个不同的变量取一个完全相同的名称会导致错误。我更喜欢以下几点:

私人INTX;
公共void setX(int newX){
x=newX;
}

相同的结果,但不可能出现错误,即您无意中引用了
x
,而实际上是指
x


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

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

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

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

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

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

以确保使用当前对象的成员。在关注线程安全的情况下,某些应用程序可能会更改错误的对象成员值,因此应将其应用于成员,以便使用正确的对象成员值


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

这在生成器模式中很有用

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

}

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

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

public class circle {
    int x;

    circle() { 
        this(1);
    }

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

@WilliamBrendelAnswer以很好的方式提供了三种不同的用例

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

    circle() { 
        this(1);
    }

    circle(int x) {
        this.x = x; 
    }
}
synchronized(this){
    // Do some thing. 
}
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");
    }
  }

}
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;
        }
    }
}
public void doSomething() {
    // More codes
    Hello.this.foo = "FOO";
    // More codes
    String s = Hello.this.getStringFromSomewhere();
    // More codes
    this.bar = s;
}