1. 程式人生 > >Java代碼塊

Java代碼塊

com 示例代碼 實例 類的初始化 接收 -c 使用 pub IT

  • 類的三大成員:成員變量、構造方法、方法,初始化代碼塊是類的第4個成員
  • 初始化塊用於對類或者對象的初始化,
  • 一個類的初始化塊可以有0~多個,按先後順序執行
  • 跟實例方法-->類方法、實例變量-->類變量一樣,也可以用static修飾初始化塊,靜態初始化塊-->非靜態初始化塊
  • 初始化塊總是先於構造器執行
  • 非靜態初始化塊
    • 非靜態初始化塊相當於是對構造器的補充,用於創建對象時給對象的初始化,在構造器之前執行
    • 如果一段初始化代碼對所有構造器完全相同,且無需接收參數,那就可以將其提取到非靜態初始化代碼塊中
    • 在繼承中,先後執行父類A的非靜態塊、構造器,再執行父類B的非靜態塊、構造器,最後才執行子類的非靜態塊、構造器
    • 實際上,經過編譯後,非靜態塊已經添加到構造器中,且位於所有構造器代碼的前面
  • 靜態初始化塊下面通過一段代碼,看看繼承中的靜態塊、非靜態塊、構造方法的執行順序
    • 靜態初始化塊用static修飾,又叫類初始化塊
    • 非靜態塊負責對對象執行初始化,而類初始化塊負責對類進行初始化,因此類初始化塊是在類初始化階段就執行
    • 靜態塊跟靜態方法一樣,不能訪問非靜態成員
    • 在繼承中,先後執行父類A的靜態塊,父類B的靜態塊,最後子類的靜態塊,然後再執行父類A的非靜態塊和構造器,然後是B類,最後執行子類的非靜態塊和構造器
    • 因為靜態塊是在類的初始化階段完成的,因此在創建某個類的第二個對象時,該類的靜態塊就不會執行了

public class Test{  
    public static void main(String[] args) {  
        C c1=new C();
        System.out.println("--------下面第二次創建C類對象---------");
        C c2=new C();
    }
}
class C extends B{
    static {
        System.out.println("C的靜態代碼塊");
    }

    {
        System.out.println("C的非靜態代碼塊");
    }

    C(){
        System.out.println("C的無參構造方法");
    }

    C(String str){
        System.out.println("C的有參構造方法");
    }
}
class B extends A{
    static {
        System.out.println("B的靜態代碼塊");
    }

    {
        System.out.println("B的非靜態代碼塊");
    }

    B(){
        System.out.println("B的無參構造方法");
    }

    B(String str){
        System.out.println("B的有參構造方法");
    }
}
class A{
    static {
        System.out.println("A的靜態代碼塊");
    }

    {
        System.out.println("A的非靜態代碼塊");
    }

    A(){
        System.out.println("A的無參構造方法");
    }

    A(String str){
        System.out.println("A的有參構造方法");
    }
}

輸出為:

A的靜態代碼塊
B的靜態代碼塊
C的靜態代碼塊
A的非靜態代碼塊
A的無參構造方法
B的非靜態代碼塊
B的無參構造方法
C的非靜態代碼塊
C的無參構造方法
--------下面第二次創建C類對象---------
A的非靜態代碼塊
A的無參構造方法
B的非靜態代碼塊
B的無參構造方法
C的非靜態代碼塊
C的無參構造方法

靜態初始化塊與靜態成員變量的執行順序

  • JVM第一次使用某個類時,在準備階段給所有靜態成員分配內存,在初始化階段初始化這些靜態成員變量,就是執行初始化代碼或者聲明成員變量時指定的初始值,執行順序與源代碼中的順序相同
  • 按源代碼中的先後順序執行,見示例代碼:
public class Test{  
    public static void main(String[] args) {  
        A a=new A();
        
        System.out.println(a.num); //輸出10,而不是6,說明先執行聲明賦值6,然後才執行靜態塊賦值10
    }
}
class A{
    public static int num=6;

    static{
        num=10;
    }
}

Java代碼塊