終於搞懂了--靜態代碼塊、構造代碼塊、構造函數的執行順序


(1)靜態代碼塊、構造代碼塊的定義區別:

 

//靜態代碼塊
static{
        System.out.println("靜態代碼塊");
    }
 
//構造代碼塊.使用{}聲明的代碼塊(和靜態代碼塊的區別是少了static關鍵字):
{
        System.out.println("構造代碼塊");
}

 

 (2)示例1:靜態代碼塊、構造代碼塊、構造函數、普通代碼塊的執行順序

public class CodeBlock {
    static{
        System.out.println("靜態代碼塊");
    }
    {
        System.out.println("構造代碼塊");
    }
    public CodeBlock(){
        System.out.println("無參構造函數");
    }
     
    public void sayHello(){
        {
            System.out.println("普通代碼塊");
        }
    }
     
    public static void main(String[] args) {
        System.out.println("執行了main方法");
         
        new CodeBlock().sayHello();;
        System.out.println("---------------");
        new CodeBlock().sayHello();;
    }
}
靜態代碼塊
執行了main方法
構造代碼塊
無參構造函數
普通代碼塊
---------------
構造代碼塊
無參構造函數
普通代碼塊
解析:
  • 靜態代碼塊最先執行,且先於static 的main方法執行
  • 創建了兩個匿名對象,但是靜態代碼塊只是調用了一次。
  • 每次創建對象的時候都會提前調用一次構造代碼塊
  • 構造代碼塊在構造函數之前執行

 (3)示例2:構造代碼塊、構造函數的執行順序

public class CodeBlock {
    public void sayHello(){
        {
            System.out.println("普通代碼塊");
        }
    }
 
    public CodeBlock(){
        System.out.println("無參構造函數");
    }
 
    {
        System.out.println("構造代碼塊");
    }
 
    static{
        System.out.println("靜態代碼塊");
    }
 
 
    public static void main(String[] args) {
        System.out.println("執行了main方法");
        new CodeBlock().sayHello();;
        System.out.println("---------------");
        new CodeBlock().sayHello();;
    }
}
靜態代碼塊
執行了main方法
構造代碼塊
無參構造函數
普通代碼塊
---------------
構造代碼塊
無參構造函數
普通代碼塊
解析:驗證了構造代碼塊優先於構造函數執行,與定義順序無關
 

(4) 示例3::構造代碼塊的作用

public class Demo01 {
    public static void main(String[] args) {
        Test test = new Test(3);  //構造代碼塊會在構造函數被調用時執行, 且在這個例子中比"this.id=id;"語句先執行,作用是給對象統一初始化數據;
        System.out.println(test);
    }
}
 
class Test{
    int id;
    String name;
    {
        this.id= 5;
        System.out.println(this.id);
        this.name = "測試";
        System.out.println("這是構造代碼塊");
    }
 
 
    Test(int id){
        this.id = id;
    }
 
 
    public String toString(){
        return "name: "+this.name +","+"id: "+ this.id ;//這里的name沒有在構造函數中賦值,但是卻有值,因為構造代碼塊已經初始化過了
    }
}
5
這是構造代碼塊
name: 測試  ,   id: 3

 

如果把下面這一段注釋掉:name就沒有被初始化,只有默認值null
{
    this.id= 5;
    System.out.println(this.id);
    //this.name = "測試";
    System.out.println("這是構造代碼塊");
}
5
這是構造代碼塊
name: null,id: 3
解析:
  • 構造代碼塊的作用是給構造函數初始化
  • 構造代碼塊要優先於構造函數執行

 

(5)總結:

構造代碼塊、靜態代碼塊的定義不同

靜態代碼塊的作用是給類初始化

構造代碼塊的作用是給構造函數初始化

 


免責聲明!

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



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