2012-05-08 97 views
1

我知道這不起作用,但它只是一個例子,所以我可以理解爲什麼它不起作用。Java - 靜態和最終變量

public class MyClass { 

    final static JButton b; 

public void myMethod() { 
    b = new JButton("Hello!"); 
} 
} 

1)爲什麼final static JButton b;行有錯誤?爲什麼當我刪除static關鍵字時,此錯誤消失?不管有沒有static關鍵字

2),有一個我不知道爲什麼這是該行b = new JButton("Hello!");錯誤?我認爲可以在方法中實例化最終變量。

回答

7

當您聲明一個靜態字段爲final時,它必須靜態初始化,無論是在靜態初始化程序塊或初始化表達式。你不能在構造函數中初始化它。

當您聲明非靜態字段爲final時,它必須在每個構造函數或初始值設定項表達式或實例初始化程序塊中初始化。

+1

只是想澄清提問者,你無法在構造函數中初始化一個'static final'的原因是因爲訪問靜態屬性不需要構造對象。 – ametren

+1

@ametren不完全 - 因爲如果它不是'final',你可以在構造函數中設置它(儘管它仍然不需要構造對象)。你不能在構造函數中設置它的原因是'static final'只能被賦值一次,而構造函數可以被調用很多次。 – yshavit

+0

@yshavit夠了! – ametren

0

靜態final變量必須直接初始化(靠近變量)或使用靜態塊。

最終變量(非靜態)必須直接聲明(靠近變量)或使用初始化塊或在對象構造函數中聲明。

1

隨着final賦值只允許立即或在構造函數。 所以只允許以下內容。

class A { 
    static final B b = new B(); 
    static final C c; 
    static { // Static initializer block. 
     c = new C(); 
    } 
    final B b2 = new B(); 
    final C c2; 
    { // Initializer block. 
     c2 = new C(); 
    } 
    final D d2; 
    A() { 
     d2 = new D(); 
    } 
} 
+0

您還可以初始化實例初始化程序塊中的非靜態最終字段。 – jbindel

+0

@Fly不是我爲'c2'做的嗎?也許我的「匿名構造函數」誤導了你。 –

+0

Doh,我沒有看到。這可能是「構造函數」這個詞使我誤入歧途。 – jbindel

1

由於該領域是static final它需要與類本身進行初始化,編譯器要求您提供比默認值以外的值。您可以提供一個默認初始值或提供的初始化塊的值:

要麼

public class MyClass { 
    final static JButton b = new JButton("Hello!"); 
} 

public class MyClass { 
    final static JButton b; 

    static{ 
     b = new JButton("Hello!"); 
    } 
} 

是有效的。

在調用時,已經太晚了,因爲預計在此時你的類已經被初始化了,並且你期望這個字段也被初始化了。

1

有些人應該重讀什麼靜態和最終忠實地是...

一個靜態變量是全球同級車的每個實例。如果你有一個Person類,其中「int static age = 0」,並且你說年齡爲++;在你的構造函數中,年齡將在每個實例中具有相同的值!意味着3x新人()預計年齡爲3,在每個Person實例中! michael.age == 3和susan.age == 3和tom.age == 3

因此,您需要爲該變量保留一些空間,並且必須初始化並聲明它!因爲這意味着「你的一個類的所有實例都有一個變量」...

接下來,最終變量必須填寫其聲明的數據,因爲您可能不會!稍後編輯該變量!像const(常量)

所以最後有靜態最終。正如你可能已經知道的那樣,這個變量是針對一個類的每一個實例,在它的聲明中被初始化並且是不可改變的!這解釋了這個類全面的「常量」(常量)變量的Java!

你走了!