Java_基礎_靜態變量一定要先聲明後賦值

這標題看着讓人很納悶,什麼叫做變量一定要先聲明後賦值?Java中的變量不都是先聲明後使用的嗎?難道還能先使用後聲明?能不能暫且不說,我們先來看一個例子,代碼如下:

package deep;


public class Client {
    public static int i = 1;
    static {
        i = 100;
    }

    public static void main(String[] args) {
        System.out.println(i);
    }

}

這段程序很簡單,輸出100嘛!對,確實是100,我們再稍稍修改一下,代碼如下:

package deep;

public class Client {
    static {
        i = 100;
    }
    public static int i = 1;

    public static void main(String[] args) {
        System.out.println(i);
    }

}

注意,變量i的聲明和賦值調換了位置,現在的問題是:這段程序能否編譯?如果可以編譯輸出是多少?還要注意:這個變量i可是先使用(也就是賦值)後聲明的。
答案是:可以編譯,沒有任何問題,輸出是1。對,你沒有看錯,輸出確實是1,而不是100。僅僅調換了一下位置,輸出就變了,而且變量i還真是先使用後聲明的,難道這世界真的顛倒了?
這要從靜態變量的誕生說起了,靜態變量是類加載時被分配到數據區(Data Area)的,它在內存中只有一個拷貝,不會被分配多次,其後的所有賦值操作都是值改變,地址則保持不變,我們知道JVM初始化變量是先聲明空間,然後再賦值的,也就是說:
int i=100;
在JVM中是分開執行,等價於:
int i;//分配地址空間
i=100;//賦值
靜態變量是在類初始化時首先被加載的,JVM會去查找類中所有的靜態聲明,然後分配空間,注意這時候只是完成了地址空間的分配,還沒有賦值,之後JVM會根據類中靜態賦值(包括靜態類賦值和靜態塊賦值)的先後順序來執行。對於程序來說,就是先聲明瞭int類型的地址空間,並把地址傳遞給了i,然後按照類中的先後順序執行賦值動作,首先執行靜態塊中i=100,接着執行i=1,那最後的結果就是i=1了。
哦,如此而已,那再問一個問題:如果有多個靜態塊對i繼續賦值呢?i當然還是等於1了,誰的位置最靠後誰有最終的決定權。
有些程序員喜歡把變量定義放到類的底部,如果這是實例變量還好說,沒有任何問題,但如果有靜態變量,而且還在靜態塊中進行了賦值,那這結果可就和你期望的不一樣的,所以遵循Java通用的開發規範“變量先聲明後使用”是一個良好的編碼風格。

發佈了133 篇原創文章 · 獲贊 11 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章