2017-04-16 60 views
6
public class StaticTest { 

    private static String a; 
    private static String b = "this is " + a; 

    public static void main(String[] args) { 
     a = "test"; 

     System.out.println(b); // prints "this is null" 
    } 

} 

我很困惑b的價值。我認爲結果應該是「這是測試」,但結果是「這是空的」。爲什麼?爲什麼這個Java靜態字段爲空?

+8

靜態字段在類加載期間被初始化。此時'a'爲'null'。 – Oleksandr

回答

4

您將字符串a添加到字符串b,但字符串a尚未定義。您應在將字符串b定義後將其添加到字符串b。

private static String a = "test"; 
private static String b = "this is a " + a; 
public static void main(String [] args){ 
    System.out.println(b); 
} 
+0

但我希望在更改時更改b。我想要這個效果。我該怎麼辦? – JianWan

2

你做

private static String a; 
private static String b = "this is " + a; 

在這一點上,anull。因此,Stringb成爲

this is null 

現在,a任何變化不會對b反映。所以,這個結果。對於預期的結果,做

private String a = "test"; 
private String b = "this is " + a; 
6

其他人解釋爲什麼它的工作原理它的方式。

但是,有些方法可以在您引用它時計算該值。

private static String a; 
private static Supplier<String> bSupplier =()->"this is " + a; 

public static void main(String[] args){ 
    a = "test"; 
    System.out.println(bSupplier.get()); //Prints "this is a test" 
} 

當您撥打bSupplier.get()時,計算出該值。如果您更改a的值,並再次調用它,則該值將反映新值。

這不是你應該經常做的事情,但對知道有用。

1

所以,展開,取出,當你運行你的程序,這些靜態字段的主要方法之前設置運行,因爲它們被定義的順序,所以a被設置爲null,並b被設置爲"this is null",然後運行主要方法,使a的值爲"test"

什麼Java那樣,當它看到

private static String b = "this is" + a; 

是需要"this is"a的附加價值到它。如果a的值稍後發生變化,則b的值不會,因爲b不存儲指向變量a的鏈接,它只會存儲分配的值。

3

但我希望改變時b。我想要這個效果。我應該怎麼做 ?

靜態字段在加載類時被初始化。
因此,在類的方法中,您無法通過簡單地更改用於在初始化過程中爲該字段賦值的變量之一的值來修改靜態字段的內容。

在你的情況下使用靜態字段爲b不符合你的需要。
b應該是相當靜態的方法getB(),根據當時的電流a值,其中調用它返回一個String實例:

public class StaticTest { 

    private static String a; 

    public static void main(String[] args) { 
     a = "test";  
     System.out.println(getB()); 
    } 

    private static String getB(){ 
     return "this is " + a;  
    } 
} 

PS:這是由史蒂芬洛斯的答案足夠接近的方式,是特定於Java 8.

+0

難道我們不能追加像,有參考嗎?我的意思是,現在我明白'+'或'.concat'只是在'String'的末尾複製'chars'。如果我們想要附加一個引用,可能是'StringBuilder',然後改變它的內容,並看到原始'String'中的變化。那可能嗎 ? –

+0

不錯,我喜歡這個。謝謝。 – JianWan

+0

@Shashwat字符串是不可變的。附加到StringBuilder的任何'String'不能對其他'String'實例產生副作用。 – davidxxx

1

當類加載器加載一個類到JVM,它在它三個階段

1)負載

2.)鏈路 (其被進一步分成三個步驟,即 (a。)中驗證,(B)製備,(C)解析)

3.)初始化

所以在製備(鏈接)階段類加載器初始化靜態變量(不是實例)並將它們設置爲它們的默認初始值(不是實際值),並且對於該字符串它爲空。

現在,在初始化階段,靜態變量被賦予它們的實際值,並且仍然anull。由於main方法將在此步驟後運行。

所以主a內部分配值"test"b已經被類裝載器初始化期間分配時a爲空,所以這是字符串b有奇怪的輸出的原因。

相關問題