2012-11-28 103 views
0

我遇到了這樣一個Java問題有關使實例變量靜:使實例變量靜

public class Student { 
private static String name; 

public Student(String name) { 
    this.name = name; 
} 

public String getName() { 
    return name; 
} 
} 

和測試:

public void testBadStatic() { 
    Student studentA = new Student("a"); 
    assertEquals("a", studentA.getName()); 
    Student studentB = new Student("b"); 
    assertEquals("b", studentB.getName()); 
    assertEquals("a", studentA.getName()); 

我認爲第二的assertEquals將失敗,因爲該名稱變量是靜態,所以它已經被分配了「a」。但是,對於第二個斷言,正確的輸出應該是正確的,對於最後的斷言,正確的輸出應該是正確的。有人能幫我理解嗎?

謝謝。

+0

你是否想讓這個測試通過,同時仍然擁有'name'字段'static'? –

+0

我認爲你混淆'靜態'和'最後' – Dylan

回答

2

公立學生(字符串名稱){

這是您的構造函數。每當你創建這個類的實例時,就調用這個「方法」。但是,靜態變量屬於該類。因此,將靜態字符串名稱設置爲一個值可更改所有現有實例的名稱。

+0

構造函數是構造函數而不是方法 – Parth

+0

你是對的 - 構造函數有些不同於方法。例如,它們沒有明確的返回類型。 – RobertG

0

嘗試:

public class Student { 
    private static String name; 

    public Student(String name) { 
     Studen.name = name; 
    } 

    public String getName() { 
     return Student.name; 
    } 
} 
2

第二斷言不會失敗,因爲該行:

Student studentB = new Student("b"); 

將更改name變量所有實例。

所以當第二個斷言來臨時,Student.name"b"。 (請注意,這是我在此引用的Student類)。

第三斷言確實會失敗,因爲name所有實例(包括studentAstudentB現在"b"

換句話說:

Student studentA = new Student("a"); 
    // studentA.name = "a" 
assertEquals("a", studentA.getName()); // This passes 
Student studentB = new Student("b"); 
    // studentB.name = "b" 
    // studentA.name = "b" 
assertEquals("b", studentB.getName()); // This passes 
assertEquals("a", studentA.getName()); // This fails 
0

靜態變量在「靜態」 「不變」的意思 - 這意味着所有實例共享相同的變量,所以第二個構造函數調用將靜態變量的值替換爲「b」。

3

我認爲你在finalstatic變量之間感到困惑。

final(但不是靜態的)變量綁定到實例,並且可以在構造函數中獲取值,或者通過靜態初始化。

Static變量綁定到類,因此它們在給定類的所有實例的一個JVM實例上共享相同的值。

最終靜態變量提供了兩個中最受限制的變量:它是有效的一個常量:不能改變,並且對於給定類的所有實例都是相同的。

結論:

this.name = name; 

語句更新的值,即綁定到類,而不是indvidual實例,所以這樣的電話後,每個實例都將「看到」相同的值 - 結果最後一次賦值操作。

+0

+1:謝謝你解釋OP的問題是:) –

0

第二個斷言會通過你在構造函數中給你的靜態變量賦「b」。這也是爲什麼第三個斷言會失敗(預計「a」,找到「b」)。