Java基礎 靜態塊、非靜態塊、構造函數的執行順序

Java中常常有一些靜態塊,這是用來在生成類以前進行的初始化,不管java還C++語言中的static,都是最早初始化好的。結構以下: 
static { 
靜態語句代碼塊 



非靜態語句代碼塊 

異同點 
相同點:都是在JVM加載類時且在構造方法執行以前執行,在類中均可以定義多個,通常在代碼塊中對一些static變量進行賦值。 
不一樣點:靜態代碼塊在非靜態代碼塊以前執行(靜態代碼塊-->非靜態代碼塊-->構造函數)。 
靜態代碼塊只在第一次new(或者只要訪問了就)執行一次,以後不在執行,而非靜態代碼塊在每new一次都會執行一次,跟構造函數同樣。非靜態代碼塊能夠在普通方法中定義(我的感受做用不大);而靜態代碼塊不行。 

Java代碼  java

public class TestStatic {
    static {
        System.out.println("基類 Static 靜態語句塊");
    }

    public TestStatic() {
        System.out.println("基類  默認無參構造器");
    }

    {
        System.out.println("基類 非靜態語句塊");
    }

    public static void Iint() {
        System.out.println("基類 Static Iint");
    }
}



public class User extends TestStatic {

    private static final long serialVersionUID = 1L;
    public final double i = Math.random();// 每次獲得的結果不同
    private final static int finalID;
    private static int finalID2;
    private int finalID3;
    
    static  {
         System.out.println("派生類 Static 靜態語句塊"); 
        finalID=1000;
    }
    
    {
        System.out.println("派生類  非靜態語句塊");  
        finalID2+=1;
        finalID3+=1;
    }
    
    /** full constructor */
    public User() {
        System.out.println("派生類  默認無參構造器");  
        
    }
    public static void IintTest() {
        System.out.println("派生類 Static Iint");
    }
}

測試語句1 dom

public static void main(String[] args) {  
        TestStatic.Iint();//User.Iint();
    }  
函數

輸出結果以下測試

基類 Static 靜態語句塊
派生類 Static 靜態語句塊
基類 Static Iintspa

測試說明了靜態代碼塊無論怎麼樣都會被執行,調用基類的靜態方法,派生類的靜態語句塊也都執行了,調用這個User.Iint(); 也是同樣的結果 。code

測試語句2 對象

public static void main(String[] args) {  
        TestStatic.Iint();//User.Iint();
         User.IintTest();
    }  
blog

輸出結果以下io

基類 Static 靜態語句塊
派生類 Static 靜態語句塊
基類 Static Iint
派生類 Static Iintclass

測試說明了 靜態語句塊執行一次,只是調用了派生類的靜態方法被執行了

測試語句3

public static void main(String[] args) {         

TestStatic.Iint();//User.Iint();
User.IintTest();
System.out.println(User.finalID);
TestStatic user = new User();

    }  

執行結果以下

基類 Static 靜態語句塊
派生類 Static 靜態語句塊
基類 Static Iint
派生類 Static Iint
1000
基類 非靜態語句塊
基類 默認無參構造器
派生類 非靜態語句塊
派生類 默認無參構造器

測試說明了 非靜態代碼塊在每new一次都會執行一次,跟構造函數同樣的次數

測試語句4

public static void main(String[] args) {  

TestStatic.Iint();//User.Iint();
User.IintTest();
System.out.println(User.finalID);
TestStatic user = new User();


System.out.println();
System.out.println("第二次初始化派生類");
User user2 = new User();


System.out.println();
System.out.println("第三次次初始化基類");
TestStatic user3 = new TestStatic ();

}

執行結果以下

基類 Static 靜態語句塊
派生類 Static 靜態語句塊
基類 Static Iint
派生類 Static Iint
1000
基類 非靜態語句塊
基類 默認無參構造器
派生類 非靜態語句塊
派生類 默認無參構造器

第二次初始化派生類
基類 非靜態語句塊
基類 默認無參構造器
派生類 非靜態語句塊
派生類 默認無參構造器

第三次次初始化基類
基類 非靜態語句塊
基類 默認無參構造器

測試說明了靜態代碼塊在非靜態代碼塊以前執行(靜態代碼塊-->非靜態代碼塊-->構造函數)。 
靜態代碼塊只在第一次new(或者只要訪問了就)執行一次,以後不在執行,而非靜態代碼塊在每new一次都會執行一次,跟構造函數同樣.


小結: 
一、靜態代碼塊是在類加載時自動執行的,非靜態代碼塊在建立對象自動執行的代碼,不建立對象不執行該類的非靜態代碼塊。 順序: 靜態代碼塊--》非靜態代碼塊--》類構造函數。 
二、在靜態方法裏面只能直接調用同類中其餘的靜態成員(包括變量和方法),而不能直接訪問類中的非靜態成員。由於對於非靜態的方法和變量,須要先建立類的實例對象後方可以使用,而靜態方法在使用前不用建立任何對象。 
三、若是某些代碼必需要在項目啓動時候就執行的時候,咱們能夠採用靜態代碼塊,這種代碼是主動執行的;須要在項目啓動的時候就初始化,

    在不建立對象的狀況下,其餘程序來調用的時候,須要使用靜態方法,此時代碼是被動執行的。 區別:靜態代碼塊是自動執行的; 靜態方法是被調用的時候才執行的; 做用:靜態代碼塊能夠用來初始化一些項目最經常使用的變量和對象;靜態方法能夠用做不建立對象也能夠能須要執行的代碼。

相關文章
相關標籤/搜索