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

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

this.method()呢?我能用吗?我应该用它吗?如果我只使用method(),默认情况下,它不会应用到当前对象吗?

268452 次浏览

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

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

除非你有重叠的变量名,这只是为了在你阅读代码时清晰。

唯一使用this.限定符的需要是当前作用域内的另一个变量共享相同的名称,并且你想引用实例成员(如William描述的那样)。除此之外,xthis.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方法。)

当然,使用this的另一个很好的理由是它会在ide中弹出智能感知:)

this不会影响生成的代码——它是编译时操作符,有或没有它生成的代码都是一样的。当你必须使用它时,取决于上下文。例如,你必须使用它,当你有一个局部变量,它掩盖了类变量你想引用类变量而不是局部变量。

edit:“生成的代码将是相同的”,我的意思当然是,当局部作用域中的某个变量没有隐藏属于类的变量时。因此

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
}

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

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

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

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

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

如果你的对象不关心线程安全,那么就没有理由指定使用哪个对象成员的值。

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


}

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

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

@William Brendel的回答很好地提供了三种不同的用例。

用例1:

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

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

它包括两个例子:

在字段中使用此方法与构造函数一起使用

用例2:

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

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

用例3:

构建器模式的实现依赖于使用this来返回修改后的对象。

参考这篇文章

保持构建器在单独的类(流畅接口)

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

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

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

关于威廉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");
}
}


}

我曾在与对象建立父子关系时看到过这种用法。但是,请注意,为了简洁起见,这里进行了简化。

有很多很好的答案,但还有一个非常次要的原因要到处放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所在的位置,直到你使用编辑器的“find”函数。然后你会因为同样的原因对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或项目时,如果你的规则包括“如果有人用记事本打开所有这些源代码,他或她应该朝自己的头开枪”,那么你完全可以不做