java的static塊執行時機
一、誤區:簡單認為JAVA靜態程式碼塊在類被載入時就會自動執行。證錯如下:
class MyClass1 {
static {//靜態塊
System.out.println("static block ");
}
}
public class Main {
Class[] classArray = {
MyClass1.class//這樣引用該類,必然需要將該類載入到虛擬機器中
};
public static void main(String[] args){
System.out.println("hello word");
}
}
執行結果:並沒有輸出" static bolck" 二、正解:static塊真正的執行時機。如果瞭解JVM原理,我們知道,一個類的執行分為以下步驟:
- 裝載
- 連線
- 初始化
其中裝載階段又三個基本動作組成:
- 通過型別的完全限定名,產生一個代表該型別的二進位制資料流
- 解析這個二進位制資料流為方法區內的內部資料結
- 構建立一個表示該型別的java.lang.Class類的例項
另外如果一個類裝載器在預先裝載的時遇到缺失或錯誤的class檔案,它需要等到程式首次主動使用該類時才報告錯誤。
連線階段又分為三部分:
- 驗證,確認型別符合Java語言的語義,檢查各個類之間的二進位制相容性(比如final的類不用擁有子類等),另外還需要進行符號引用的驗證。
- 準備,Java虛擬機器為類變數分配記憶體,設定預設初始值。
- 解析(可選的) ,在型別的常量池中尋找類,介面,欄位和方法的符號引用,把這些符號引用替換成直接引用的過程。
當一個類被主動使用時,Java虛擬就會對其初始化,如下六種情況為主動使用:
- 當建立某個類的新例項時(如通過new或者反射,克隆,反序列化等)
- 當呼叫某個類的靜態方法時
- 當使用某個類或介面的靜態欄位時
- 當呼叫Java API中的某些反射方法時,比如類Class中的方法,或者java.lang.reflect中的類的方法時
- 當初始化某個子類時
- 當虛擬機器啟動某個被標明為啟動類的類(即包含main方法的那個類)
Java編譯器會收集所有的類變數初始化語句和型別的靜態初始化器,將這些放到一個特殊的方法中:clinit。
實際上,static塊的執行發生在“初始化”的階段。初始化階段,jvm主要完成對靜態變數的初始化,靜態塊執行等工作。
下面我們看看執行static塊的幾種情況:
1、第一次new A()的過程會列印"";因為這個過程包括了初始化
2、第一次Class.forName("A")的過程會列印"";因為這個過程相當於Class.forName("A",true,this.getClass().getClassLoader());
3、第一次Class.forName("A",false,this.getClass().getClassLoader())的過程則不會列印""。因為false指明瞭裝載類的過程中,不進行初始化。不初始化則不會執行static塊。
參考資料:《深入Java虛擬機器》
相關文章
- Java的執行機制分析!Java
- Java虛擬機器-執行時資料區Java虛擬機
- Java執行時資料Java
- Java 虛擬機器中的執行時資料區分析Java虛擬機
- Java技術分享:Java的執行機制Java
- Java虛擬機器--方法區(執行時常量池)Java虛擬機
- java虛擬機器——執行時資料區域Java虛擬機
- Java執行緒的CPU時間片Java執行緒
- java的執行時資料區域Java
- MySQL checkpoint執行時機MySql
- Java 虛擬機器執行時資料區詳解Java虛擬機
- Java 執行時的記憶體劃分Java記憶體
- 淺聊java執行機制Java
- Vue nextTick執行時機分析Vue
- java中的Static、final、Static final各種用法Java
- Java虛擬機器執行時資料區域劃分Java虛擬機
- Golang實現JAVA虛擬機器-執行時資料區GolangJava虛擬機
- Java 虛擬機器之二:Java語言的執行機制Java虛擬機
- React 中 render 函式的執行時機React函式
- 關於Java虛擬機器執行時資料區域的總結Java虛擬機
- 在Java程式中列印java執行時引數Java
- static變數,static程式碼塊,建構函式,程式碼塊等的載入順序變數C程式函式
- liunx進行 idea java 執行時反彙編IdeaJava
- java synchronize - 執行緒同步機制Java執行緒
- Java 執行時(RUNTIME)註解詳解Java
- Java-JVM-執行時資料區JavaJVM
- Java如何測量方法執行時間Java
- Java中建構函式、靜態程式碼塊、程式碼塊的執行順序Java函式
- Java的static修飾符Java
- Java 的 static 關鍵字Java
- Java中static的含義Java
- Java實現終止執行緒池中正在執行的定時任務Java執行緒
- 深入理解Java虛擬機器筆記之一Java執行時資料區Java虛擬機筆記
- 自己動手實現springboot執行時執行java原始碼(執行時編譯、載入、註冊bean、呼叫)Spring BootJava原始碼編譯Bean
- 詳解Java 虛擬機器(第①篇)——執行時資料區域Java虛擬機
- Java虛擬機器詳解(二)------執行時記憶體結構Java虛擬機記憶體
- Java程式執行記憶體機制Java記憶體
- JAVA多執行緒與鎖機制Java執行緒
- java學習回顧---執行緒和同步程式碼塊Java執行緒