初始化-主動使用實例分析

根據上一節的理論我們知道,每個類的接口被Java程序“首次主動使用”時才初始化,這一節我們就通過具體的實例來驗證一下

  1. 創建類的實例
public class MyTest1 {
    public static void main(String[] args) {
        new MyParent1();
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

運行程序,輸出:

MyParent static block

類的靜態代碼塊被執行了,說明類進行了初始化

  1. 訪問某個類或接口的靜態變量,或者對該靜態變量賦值
public class MyTest1 {
    public static void main(String[] args) {
        System.out.println(MyParent1.str);
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

運行程序,輸出:

MyParent static block
hello world
  1. 調用類的靜態方法
public class MyTest1 {
    public static void main(String[] args) {
        MyParent1.print();
    }
}
class MyParent1 {
    public static String str = "hello world";

    public static void print(){
        System.out.println(str);
    }

    static {
        System.out.println("MyParent static block");
    }
}

運行程序,輸出:

MyParent static block
hello world
  1. 反射
public class MyTest1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.shengsiyuan.jvm.classloader.MyParent1");
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

運行程序,輸出:

MyParent static block
  1. 初始化一個類的子類
public class MyTest1 {
    public static void main(String[] args) throws ClassNotFoundException {
        new MyChild1();
    }
}
class MyParent1 {
    public static String str = "hello world";

    static {
        System.out.println("MyParent static block");
    }
}

class MyChild1 extends MyParent1 {
    public static String str2 = "welcome";

    static {
        System.out.println("MyChild1 static block");
    }
}

運行程序,輸出:

MyParent static block
MyChild1 static block
  1. Java虛擬機啟動時被表明為啟動類的類
public class MyTest1 {
    static {
        System.out.println("MyTest1 static block");
    }
    public static void main(String[] args) throws ClassNotFoundException {
        
    }
}

運行程序,輸出:

MyTest1 static block

非主動使用注意點

以上實例都是對主動使用的驗證,我們來看一下下面這個程序

public class MyTest1 {
  public static void main(String[] args) throws ClassNotFoundException {
      System.out.println(MyChild1.str);
  }
}
class MyParent1 {
  public static String str = "hello world";

  static {
      System.out.println("MyParent static block");
  }
}

class MyChild1 extends MyParent1 {
  static {
      System.out.println("MyChild1 static block");
  }
}

運行程序,輸出:

MyParent static block
hello world

我們可以看到,MyChild1 static block并沒有打印出來,這里我們調用MyChild1.str明明是對類的靜態變量的訪問,但是MyChild1卻沒有被初始化,所以這里要注意的一點就是:

對于靜態字段來說,只有直接定義了該字段的類才會被初始化


參考資料:
圣思園JVM課程

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,740評論 18 399
  • 6.6日咖啡冥想 我的目標是帶領C2月業績上百萬 所以我的咖啡冥想內容是: 1,把自己上個月帶團隊的過程中的經驗進...
    艷敏姐閱讀 320評論 0 0
  • 分享一下我的所見所聞,再加上我的所感。 我發現我們身邊的朋友們對于外國人都有一種神秘感。我覺得其實都是人類,都有人...
    長春藤0805閱讀 344評論 0 1
  • 無論受了什么傷 都請在那一天內結束悲傷 你明白的 這個城市的車水馬龍 從來都不會在乎你昨天的泣不成聲
    無言以若閱讀 273評論 0 0