2010-03-11 47 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; 
    } 
    ... 
}