2015-03-30 77 views
3
class Test { 
    static final String name; 

    {  
     name = "User"; 
     /* shows error. As i have to assign User as default value */ 
    } 
    final String name1; 

    { 
     name1 = "User"; // This works but why the above one does not works 
    } 
}  

我能夠使用靜態塊分配值,但不能通過實例阻止原因?爲什麼最終的靜態變量不能在實例塊中賦值?

+0

也許你的意思是「怎麼做」,而不是原因。除非你對語言語法和設計背後的哲學有疑問。 – 2015-03-30 18:46:47

回答

5

因爲是static final,所以它必須在一次靜態上下文被初始化 - 當變量被聲明或在static initialization block

static {  
    name = "User"; 
} 

編輯:靜態成員屬於類,和非靜態成員屬於該類的每個實例。如果要在實例塊中初始化一個靜態變量,那麼每次創建該類的新實例時都會初始化它。這意味着它在此之前不會被初始化,並且可以被初始化多次。由於它是staticfinal,它必須初始化一次(對於該類,對於每個實例不是一次),因此您的實例塊將不會執行。

也許你想在Java中研究更多關於static vs. non-static variables的內容。

EDIT2:以下是可能有助於您理解的示例。

class Test { 
    private static final int a; 
    private static int b; 
    private final int c; 
    private int c; 

    // runs once the class is loaded 
    static { 
     a = 0; 
     b = 0; 
     c = 0; // error: non-static variables c and d cannot be 
     d = 0; // referenced from a static context 
    } 

    // instance block, runs every time an instance is created 
    { 
     a = 0; // error: static and final cannot be initialized here 
     b = 0; 
     c = 0; 
     d = 0; 
    } 
} 

所有非註釋行都有效。如果我們有

// instance block 
    { 
     b++; // increment every time an instance is created 
     // ... 
    } 

然後b將工作作爲創建的實例數的計數器,因爲它是static,並在非靜態實例塊遞增。

+0

雅我同意你,但這是如何工作final String name1; { name1 =「User」; } – Prasanna 2015-03-30 19:26:47

+0

@Prasanna,它的工作原理是因爲你的變量是非靜態的,它屬於實例。因此,每次創建新實例時'name1'都將由實例塊初始化一次。 – ericbn 2015-03-30 19:43:40

2

因爲靜態字段必須在加載類時進行初始化。實例塊在類加載之後被調用(在新實例建立時),所以final static字段不能被改變。 U可以使用static塊來初始化final static fields

0

靜態字段在加載類時被初始化。這就是爲什麼它不會像你試圖使它工作一樣。

0

SIB:當類被加載它被執行,整個執行

IIB只有一次執行:在執行時調用構造函數,但構造函數執行前。所以它執行的次數與構造函數的執行次數相同。

讓我們看看示例

package com.kb.instanceblock;

公共類SIB1 {

static { 
    System.out.println("SIB"); 
} 


{ 
    System.out.println("IIB"); 
} 

public SIB1() { 
    System.out.println("Constructor"); 
} 

public static void main(String[] args) { 

SIB1 SIB =新SIB1(); }

} 輸出

SIB IIB 構造

所以當類被加載,SIB被調用並且每當構造被調用,IIB執行,然後構造塊執行。

因爲我們知道常數變量的值應該在他們的聲明中定義的,所以我們不能用IIB分配靜態常量變量

相關問題