[改善Java代碼]靜態變量一定要先聲明后賦值


建議32: 靜態變量一定要先聲明后賦值

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

1 public class Client {  
2      public static  int i=1;  
3      static{  
4          i=100;  
5      }  
6      public static void main(String[] args) {  
7           System.out.println(i);  
8     }  
9 } 

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

 1 public class Client {
 2     static {
 3         i = 100;
 4     }
 5     public static int i = 1;
 6 
 7     public static void main(String[] args) {
 8         System.out.println(i);
 9     }
10 }

注意,變量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通用的開發規范“變量先聲明后使用”是一個良好的編碼風格。

注意 再次重申變量要先聲明后使用,這不是一句廢話。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM