Java中靜態代碼塊、構造代碼塊、構造方法的執行順序及靜態代碼塊的執行次數

先引入一份代碼:

public class A{
 	public A(){
	    System.out.println("構造方法中a=30");
 	    a=30;
	 }
	 
	 {
 	    System.out.println("構造代碼塊1中a=40");
 	    a=40;
	 }
	 int a=init();
 
	 {
	     System.out.println("構造代碼塊2中a=60");
	     a=60;
	 }
	 
	 public int init(){
 	     System.out.println("初始化中a=90");
 	     return 90;
	 }
	 
 	static{
  	     System.out.println("靜態代碼塊1中B=100");
	     B=100;
	 }
	 static int B=staticInit();
 
 	static{ 
  	     System.out.println("靜態代碼塊2中B=400");
 	     B=400;
	 }

	 public static int staticInit(){   
     	     System.out.println("初始化中B=500");
 	     return 500;
	 }
	 
	 public static void main(String[] args){
 	     A p=new A();
     	     A q=new A();
 	 }
  }

輸出結果爲:

   靜態代碼塊1中B=100
   初始化中B=500
   靜態代碼塊2中B=400  
   構造代碼塊1中a=40        
   初始化中a=90     
   構造代碼塊2中a=60    
  構造方法中a=30     
   構造代碼塊1中a=40    
   初始化中a=90     
  構造方法中a=30

根據以上的運行結果我們會不由自主的產生幾個問題,例如:

1.什麼是靜態代碼塊?

所謂的代碼塊就是一段獨立的代碼空間,那什麼是靜態代碼塊呢?說白了,靜態代碼塊就是用static修飾的代碼塊。

2.它們的執行順序是什麼?

執行順序:(優先級從高到低)靜態代碼塊>mian方法>構造代碼塊>構造方法。

3.爲什麼在顯示結果中靜態代碼塊的內容只顯示了一次?

    在類加載的init階段,類的類構造器中會收集所有的static塊和字段並執行,static塊只執行一次,由JVM保證其只執行一次。或者可以這樣認爲:static代碼塊只在類加載時執行,類是用類加載器來讀取的,類加載器是帶有一個緩存區的,它會把讀取到的類緩存起來,所以在一次虛擬機運行期間,一個類只會被加載一次,這樣的話靜態代碼塊只會運行一次。

4.靜態代碼塊的顯著特點是什麼?

隨着類的加載而執行,而且只執行一次

5.static{ }(靜態代碼塊)與{ }(非靜態代碼塊)的異同點

相同點:都是在JVM加載類時且在構造方法執行之前執行,在類中都可以定義多個。

不同點:靜態代碼塊在非靜態代碼塊之前執行(靜態代碼塊—>非靜態代碼塊—>構造方法)。
    靜態代碼塊只在第一次new執行一次,之後不再執行,而非靜態代碼塊在每new
    一次就執行一次。
    
總結:靜態代碼塊,在虛擬機加載類的時候就會加載執行,而且只執行一次;  
     非靜態代碼塊,在創建對象的時候(即new一個對象的時候)執行,每次創建對象都會執行一次

6.靜態代碼塊和靜態方法的區別?

1)靜態代碼塊是自動執行的;	靜態方法是被調用的時候才執行的。
2)靜態代碼塊可用來初始化一些項目最常用的變量或對象;靜態方法可用作不創建對象也可能需要執行的代碼。

7.關於靜態代碼塊的認識?

1)靜態代碼塊只能定義在類裏面,它獨立於任何方法,不能定義在方法裏面。
2)靜態代碼塊裏面的變量都是局部變量,只在本塊內有效。
3)靜態代碼塊會在類被加載時自動執行,而無論加載者是JVM還是其他的類。
4)一個類中允許定義多個靜態代碼塊,執行的順序根據定義的順序進行。
5)靜態代碼塊只能訪問類的靜態成員,而不允許訪問實例成員。實例方法可以訪問靜態和實例成員。

8.不允許靜態方法訪問實例成員變量的原因?

因爲實例成員變量是屬於某個對象的,而靜態方法在執行時,並不一定存在對象。
同樣,因爲實例方法可以訪問實例成員變量,如果允許靜態方法調用實例方法,將間接地允許它使用實例成員變量,所以靜態方法也不能調用實例方法。基於同樣的道理,靜態方法中也不能使用關鍵字this。
  1. 靜態代碼優先於非靜態的代碼的原因?
    靜態代碼優先於非靜態的代碼,是因爲被static修飾的成員都是類成員,會隨着JVM加載類的時候加載而執行,而沒有被static修飾的成員也被稱爲實例成員,需要創建對象纔會隨之加載到堆內存。所以靜態的會優先非靜態的。 

總結:
靜態代碼塊會隨着類的加載而執行,而且只執行一次。當所有的靜態代碼塊都執行結束後會執行main函數中的輸出語句,然後會去執行非靜態代碼塊,接着是執行構造方法。

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