java提升篇-----代碼塊

轉載  http://www.cnblogs.com/chenssy/p/3413229.html

 本身添加部分
  構造代碼塊在變量初始化以後執行;也符合java編程思想中  ---- 靜態構造代碼塊>變量初始化> 普通構造代碼塊
 

      在編程過程當中咱們可能會遇到以下這種形式的程序:html

public class Test {
    {
        ////
    }
}

      這種形式的程序段咱們將其稱之爲代碼塊,所謂代碼塊就是用大括號({})將多行代碼封裝在一塊兒,造成一個獨立的數據體,用於實現特定的算法。通常來講代碼塊是不能單獨運行的,它必需要有運行主體。在Java中代碼塊主要分爲四種:前端

1、 普通代碼塊

      普通代碼塊是咱們用得最多的也是最廣泛的,它就是在方法名後面用{}括起來的代碼段。普通代碼塊是不可以單獨存在的,它必需要緊跟在方法名後面。同時也必需要使用方法名調用它。java

public class Test {
    public void test(){
        System.out.println("普通代碼塊");
    }
}

2、 靜態代碼塊

      想到靜態咱們就會想到static,靜態代碼塊就是用static修飾的用{}括起來的代碼段,它的主要目的就是對靜態屬性進行初始化。算法

public class Test {
    static{
        System.out.println("靜態代碼塊");
    }
}

3、 同步代碼塊

      使用 synchronized 關鍵字修飾,並使用「{}」括起來的代碼片斷,它表示同一時間只能有一個線程進入到該方法塊中,是一種多線程保護機制。編程

4、 構造代碼塊

      在類中直接定義沒有任何修飾符、前綴、後綴的代碼塊即爲構造代碼塊。咱們明白一個類必須至少有一個構造函數,構造函數在生成對象時被調用。構造代碼塊和構造函數同樣一樣是在生成一個對象時被調用,那麼構造代碼在何時被調用?如何調用的呢?看以下代碼:多線程

複製代碼
public class Test {
    /**
     * 構造代碼
     */
    {
        System.out.println("執行構造代碼塊...");
    }
    
    /**
     * 無參構造函數
     */
    public Test(){
        System.out.println("執行無參構造函數...");
    }
    
    /**
     * 有參構造函數
     * @param id  id
     */
    public Test(String id){
        System.out.println("執行有參構造函數...");
    }
}
複製代碼

      上面定義了一個很是簡單的類,該類包含無參構造函數、有參構造函數以及構造代碼塊,同時在上面也提過代碼塊是沒有獨立運行的能力,他必需要有一個能夠承載的載體,那麼編譯器會如何來處理構造代碼塊呢?編譯器會將代碼塊按照他們的順序(假若有多個代碼塊)插入到全部的構造函數的最前端,這樣就能保證無論調用哪一個構造函數都會執行全部的構造代碼塊。上面代碼等同於以下形式:函數

複製代碼
public class Test {
    /**
     * 無參構造函數
     */
    public Test(){
        System.out.println("執行構造代碼塊...");
        System.out.println("執行無參構造函數...");
    }
    
    /**
     * 有參構造函數
     * @param id  id
     */
    public Test(String id){
        System.out.println("執行構造代碼塊...");
        System.out.println("執行有參構造函數...");
    }

}
複製代碼

      運行結果post

複製代碼
public static void main(String[] args) {
        new Test();
        System.out.println("----------------");
        new Test("1");
    }
------------
Output:
執行構造代碼塊...
執行無參構造函數...
----------------
執行構造代碼塊...
執行有參構造函數...
複製代碼

      從上面的運行結果能夠看出在new一個對象的時候老是先執行構造代碼,再執行構造函數,可是有一點須要注意構造代碼不是在構造函數以前運行的,它是依託構造函數執行的。正是因爲構造代碼塊有這幾個特性,因此它經常使用於以下場景:spa

      一、 初始化實例變量線程

      若是一個類中存在若干個構造函數,這些構造函數都須要對實例變量進行初始化,若是咱們直接在構造函數中實例化,一定會產生不少重複代碼,繁瑣和可讀性差。這裏咱們能夠充分利用構造代碼塊來實現。這是利用編譯器會將構造代碼塊添加到每一個構造函數中的特性。

      二、 初始化實例環境

      一個對象必須在適當的場景下才能存在,若是沒有適當的場景,則就須要在建立對象時建立此場景。咱們能夠利用構造代碼塊來建立此場景,尤爲是該場景的建立過程較爲複雜。構造代碼會在構造函數以前執行。

      上面兩個經常使用場景都充分利用構造代碼塊的特性,可以很好的解決在實例化對象時構造函數比較難解決的問題,利用構造代碼不只能夠減小代碼量,同時也是程序的可讀性加強了。特別是當一個對象的建立過程比較複雜,須要實現一些複雜邏輯,這個時候若是在構造函數中實現邏輯,這是不推薦的,由於咱們提倡構造函數要儘量的簡單易懂,因此咱們可使用構造代碼封裝這些邏輯實現部分。

5、 靜態代碼塊、構造代碼塊、構造函數執行順序

      從詞面上咱們就能夠看出他們的區別。靜態代碼塊,靜態,其做用級別爲類,構造代碼塊、構造函數,構造,其做用級別爲對象。

      一、 靜態代碼塊,它是隨着類的加載而被執行,只要類被加載了就會執行,並且只會加載一次,主要用於給類進行初始化。

      二、 構造代碼塊,每建立一個對象時就會執行一次,且優先於構造函數,主要用於初始化不一樣對象共性的初始化內容和初始化實例環境。

      三、 構造函數,每建立一個對象時就會執行一次。同時構造函數是給特定對象進行初始化,而構造代碼是給全部對象進行初始化,做用區域不一樣。

      經過上面的分析,他們三者的執行順序應該爲:靜態代碼塊 > 構造代碼塊 > 構造函數。

複製代碼
public class Test {
    /**
     * 靜態代碼塊
     */
    static{
        System.out.println("執行靜態代碼塊...");
    }
    
    /**
     * 構造代碼塊
     */
    {
        System.out.println("執行構造代碼塊...");
    }
    
    /**
     * 無參構造函數
     */
    public Test(){
        System.out.println("執行無參構造函數...");
    }
    
    /**
     * 有參構造函數
     * @param id
     */
    public Test(String id){
        System.out.println("執行有參構造函數...");
    }
    
    public static void main(String[] args) {
        System.out.println("----------------------");
        new Test();
        System.out.println("----------------------");
        new Test("1");
    }
}
-----------
Output:
執行靜態代碼塊...
----------------------
執行構造代碼塊...
執行無參構造函數...
----------------------
執行構造代碼塊...
執行有參構造函數...

6、變量(字段)初始化 靜態代碼塊、構造代碼塊、構造函數執行順序

class Soap {
private String s;

Soap() {
System.out.println("Soap()");
s = new String("Constructed");
}

public String toString() {
return s;
}
}

public class Test {

private Soap soap=new Soap();
/**
* 靜態代碼塊
*/
static{
System.out.println("執行靜態代碼塊...");
}

/**
* 構造代碼塊
*/
{
System.out.println("執行構造代碼塊...");
}

/**
* 無參構造函數
*/
public Test(){
System.out.println("執行無參構造函數...");
}

/**
* 有參構造函數
* @param id
*/
public Test(String id){
System.out.println("執行有參構造函數...");
}

public static void main(String[] args) {
System.out.println("----------------------");
new Test();
System.out.println("----------------------");
new Test("1");
}
}

 

output:

執行靜態代碼塊...----------------------Soap()//看起來是-----這個字段初始化先執行而後纔是構造代碼塊,但實際上不是的,他們的級別應該是一致的,只由於字段寫在前面了。。。構造代碼塊和字段初始化通級別。執行構造代碼塊...執行無參構造函數...----------------------Soap()執行構造代碼塊...執行有參構造函數...

相關文章
相關標籤/搜索