2010-03-11 125 views
60

在Java中使用this关键字的最佳做法是什么?例如,我有下面的类:Java - 何时使用'this'关键字

class Foo { 
    Bar bar; 

    public Foo(Bar bar) { 
     this.bar = bar; 
    } 
} 

这很好,所有的,但如果我改变在构造函数中的语句

bar = bar; 

那么为什么要使用Java是足够聪明的知道发生了什么this关键字? (我认识到在某些情况下,完全有必要使用它,我只是要求这样的情况)。实际上,我倾向于纯粹为了可读性而使用关键字,但常见的做法是什么?使用它在店里让我的代码看起来有点凌乱,例如

boolean baz; 
int someIndex = 5; 
this.baz = this.bar.getSomeNumber() == this.someBarArray[this.someIndex].getSomeNumber(); 

显然代码穷一点,但它说明了我的例子。在这些情况下是否只是个人偏好?

+3

相同的问题发布于2天前:http://stackoverflow.com/questions/2411270/when-should-i-use-this-in-a-class还有更多的模糊: http://www.google.com/search?q=java+when+use+this+keyword+site%3Astackoverflow.com – BalusC 2010-03-11 22:16:19

+0

我的不好,我有一个(显然非常)快速搜索使用SO搜索,但没有找到任何东西... – jackbot 2010-03-11 22:20:48

+0

正如其他人指出的,你正在做自我(参数)上面的任务。但是我的经验法则是在使程序更易读*时使用'this'。如果你对成员变量使用某种命名约定(例如'_bar'或'mBar'),那么编写'this._bar'就是额外的噪声,恕我直言。 – 2010-03-11 22:41:12

回答

69

但Java是足够聪明的知道如果我改变构造函数中的语句

bar = bar; 

FALSE发生了什么事!它编译但它不会做你认为它做的事!

至于何时使用它,很多都是个人喜好。我喜欢在我的公共方法中使用this,即使它没有必要,因为这是接口发生的地方,很高兴声明什么是我的,什么不是。

为参照,你可以检查Oracle的Java教程了约this.subject ;-)

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

+11

这就是为什么我想标记所有参数变量为最终。 – crowne 2010-03-11 22:31:15

+0

是的,它只是将构造器中的变量栏重新分配给自己。这是因为bar已经在范围中定义了,它覆盖了Bar栏中的一个。 – 2010-03-12 01:04:47

3

这是一种个人偏好 - 选择一种风格并坚持下去。我个人使用this但其他人认为它是多余的。

3

根据惯例,你可以使用它的可读性。它强调了它是一个对象变量的事实。

我也喜欢使用与变量同名的setter参数(在方法签名中看起来更好)。在这种情况下,您需要this

11

其实

baz = baz 

会提出这个警告

分配给变量巴兹没有 效果

那么,你认为是错的,局部范围覆盖类属性所以你必须使用this keywo rd明确地将变量分配给类属性。

否则,分配给变量的变量只是作为参数传递的变量,而类别被忽略。这就是为什么this是有用的,这不是一个可读性的事实,它是明确决定你在说哪个baz的事实。

只要不使用它会引起歧义(或编译器警告,这是更重要的),我会说

使用this,否则见好就收吧。因为它的目的正是为了解决默认假设(首先检查当地人,然后检查班级属性)是否不明确。

12

你应该使用它,当你有一个与字段同名的参数,否则你会遇到问题。它会编译,但不一定会按你想要的去做。

至于其他地方,除非出于可读性的原因,否则不要使用它。如果你在任何地方使用它,20%的代码将包含“this”这个词!

+0

虽然有争议的是,显式的'this'关键字可以有所帮助。像Python和Rust这样的语言实际上需要它('self'),我从来没有将这种明确性视为否定。 – phoenix 2017-07-28 12:03:49

+0

明智的答案,简短,简明扼要地点 – 2017-12-30 18:57:30

6
public Foo(Bar bar) { 
    this.bar = bar; 
} 

是不一样的

public Foo(Bar bar) { 
    bar = bar; 
} 

在第二种情况下,范围栏的参数,所以你把它分配给自己。 this.bar仍然是null

1

个人喜好,但我用它来解决歧义只,并在极少数情况下,我想假设分配的变量是一个字段。有一些项目在人们使用“this.field”的每个字段参考。我发现这种做法在视觉上分散注意力,让人讨厌,但你应该准备好偶尔看看这样的代码。

我暗暗地以为地狱里有一个特别的地方,那些编写500行的类有275个'这个'关键字,但是这个风格在一些开源项目中是可以找到的,所以对于他自己来说我猜。

+0

+1如果使用这个。*找到使用这个地方*非常烦人。如果您使用现代IDE,并且正确设计类,那么您将永远不会遇到必须弄清楚所引用的变量是什么(属性,局部变量等) – helpermethod 2010-03-11 23:46:27

2

我总是尝试在本地类对象上使用this关键字。

我用它在视觉上提醒我,如果一个对象是静态对象或类对象。

它帮助我和编译器区分方法参数和本地类对象。

public void setValue(int value){ 
    this.value = value; 
} 

它帮助我在视觉上提醒我,如果有一个内/嵌套/匿名类这样的本地对象从封装类对象区分开来。因为如果没有this前缀,我约定会提醒我,这是封装类的一个对象

public class Hello{ 
    public int value = 0; 
    public boolean modal = false; 

    public class Hellee{ 
    public int value = 1; 
    public getValue(){ 
     if (modal) 
     return 0; 
     return this.value; 
    } 
    } 
} 
10

this关键字是指在其上调用一些方法类的对象。
例如:

public class Xyz { 
    public Xyz(Abc ob) 
    { 
     ob.show(); 
    } 
} 

public class Abc { 
    int a = 10; 

    public Abc() 
    { 
     new Xyz(this); 
    } 

    public void show() 
    { 
     System.out.println("Value of a " + a); 
    } 

    public static void main(String s[]) 
    { 
     new Abc(); 
    } 
} 

在这里,在Abc()我们呼吁Xyz()这就需要ABC等级的对象。所以我们可以通过this,而不是新Abc(),因为如果我们在这里通过新Abc()它会再次调用自身和再次。

另外我们用这个来区分方法的类和局部变量的变量。例如

class Abc { 
    int a; 

    void setValue(int a) 
    { 
     this.a = a; 
    } 
} 

这里this.a是指类别Abc的变量a。因此,您使用新的Abc().a;具有相同的效果。

所以你可以说this是指当前类的对象。

0

将其用于克隆对象(通过将自身的引用传递给复制构造函数)。

用于继承Cloneable的对象。

public Foo implements Cloneable { 
    private String bar; 

    public Foo(Foo who) { 
    bar = who.bar; 
    } 

    public Object getClone() { 
    return new Foo(this); //Return new copy of self. 
    } 
} 
2
void set(int real) 
{ 
    this.real = real; 
} 

这里this是使用关键字时,有实例变量是一样的局部变量。
另一种使用this是构造函数重载。它可以在重载的构造函数中调用构造函数。

7

是很常见的使用这个关键字明确的构造函数调用。您可以从documentation中看到一个示例。

public class Rectangle { 
    private int x, y; 
    private int width, height; 

    public Rectangle() { 
     this(0, 0, 1, 1); 
    } 
    public Rectangle(int width, int height) { 
     this(0, 0, width, height); 
    } 
    public Rectangle(int x, int y, int width, int height) { 
     this.x = x; 
     this.y = y; 
     this.width = width; 
     this.height = height; 
    } 
    ... 
}