Java的靜態代碼塊是否會在類被載入時自動執行?

来源:http://www.cnblogs.com/winterfells/archive/2017/11/28/7908189.html
-Advertisement-
Play Games

JAVA靜態代碼塊會在類被載入時自動執行? 一、先看Java靜態方法,靜態變數 http://www.cnblogs.com/winterfells/p/7906078.html 靜態代碼塊 在類中,可以將某一塊代碼聲明為靜態的,這樣的程式塊叫靜態初始化段。靜態代碼塊的一般形式如下: 編譯通過後,用 ...


JAVA靜態代碼塊會在類被載入時自動執行?

一、先看Java靜態方法,靜態變數

http://www.cnblogs.com/winterfells/p/7906078.html

 

靜態代碼塊

 

在類中,可以將某一塊代碼聲明為靜態的,這樣的程式塊叫靜態初始化段。靜態代碼塊的一般形式如下:

static {
    語句序列
}
public class staticBlock{

        //定義一個普通的main()方法

        public static void main(String args[]){

        System.out.println("This is main method."); 

       }

      //定義一個靜態代碼塊

     static{

         System.out.println("This is static block.");

         int stVar = 0;   //這是一個局部變數,只在本塊內有效

      }

}

編譯通過後,用java命令載入本程式,會得到如下輸出:

This is static block.

This is main method.

從以上輸出結果中可以看出,靜態代碼塊甚至在main方法之前就被執行。在main()方法中可以完成的任務在靜態代碼塊中都可以完成。但是二者在執行上仍然有一些區別,main方法是整個程式啟動的入口,而靜態代碼塊是存在於某個類中的一個過程。

 

那是不是只要類被載入了就一定會執行靜態代碼塊?

 

二、再看JVM類載入的過程

  1. 裝載
  2. 連接
  3. 初始化

    其中裝載階段又三個基本動作組成:

  1.     通過類型的完全限定名,產生一個代表該類型的二進位數據流
  2.     解析這個二進位數據流為方法區內的內部數據結
  3.     構創建一個表示該類型的java.lang.Class類的實例

    另外如果一個類裝載器在預先裝載的時遇到缺失或錯誤的class文件,它需要等到程式首次主動使用該類時才報告錯誤。

 

    連接階段又分為三部分:

  1. 驗證,確認類型符合Java語言的語義,檢查各個類之間的二進位相容性(比如final的類不用擁有子類等),另外還需要進行符號引用的驗證。
  2. 準備,Java虛擬機為類變數分配記憶體,設置預設初始值。
  3. 解析(可選的) ,在類型的常量池中尋找類,介面,欄位和方法的符號引用,把這些符號引用替換成直接引用的過程。

 當一個類被主動使用時,Java虛擬就會對其初始化,如下五種情況為主動使用:

  1. 遇到new, getstatic, putstatic 或者 invokestatic 4條位元組碼指令時,如果類沒有進行過初始化,則需要先進行初始化。這些場景包括:使用new關鍵字實例化對象,讀取或者設置一個類的靜態欄位以及調用一個類的靜態方法的時候。

  2. 使用java.lang.reflect包的方法進行反射調用的時候,如果類沒有初始化,需要進行初始化。

  3. 當初始化一個類的時候發現其父類還沒有初始化,需要對父類進行初始化。

  4. JVM啟動時,用戶指定的包含main方法的那個類,需要首先進行初始化。

  5. JDK1.7中動態語言的支持,解析java.lang.invoke.MethodHandle的結果為REF_getStatic, REF_putStatic, REF_invokeStatic方法的句柄時,對應的類沒有初始化的時候。

 

實際上,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塊。

 

再看這個例子

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");
    }

}

結果:

hello world

 

所以結論是不初始化則不會執行static塊。

 

參考:《深入理解java虛擬機》

http://blog.csdn.net/jiese1990/article/details/40154329

http://www.cnblogs.com/ivanfu/archive/2012/02/12/2347817.html

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 演示產品下載地址:http://www.jinhusns.com ...
  • 返回總目錄 本小節目錄 Consolidate Duplicate Conditional Fragments(合併重覆的條件片段) Remove Control Flag(移除控制標記) 3Consolidate Duplicate Conditional Fragments(合併重覆的條件片段) ...
  • 使用jdbcTemplate 原理是把載入驅動Class.forName("com.mysql.jdbc.Driver"); 和連接資料庫Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/sw_datab ...
  • 1.首先要下載PHPExcel放到vendor文件夾下,我的路徑是:項目/vendor/PHPExcel/,把下載的PHPExcel文件放在這裡 2.前端代碼 3.後臺代碼 輸出結果: 註意: 引入第三方類庫使用vendor();是按照命名空間的形式。底層代碼會把“ . ”自動替換成" / ",所以 ...
  • 1 非對稱加密演算法 1.1 概述 1976年,美國學者Dime和Henman為解決信息公開傳送和密鑰管理問題,提出一種新的密鑰交換協議,允許在不安全的媒體上的通訊雙方交換信息,安全地達成一致的密鑰,這就是“公開密鑰系統”。 與對稱加密演算法不同,非對稱加密演算法需要兩個密鑰:公開密鑰(publickey ...
  • 原文:http://blog.csdn.net/u012152619/article/details/51485297 一般來說,上面的幾個配置項對任何項目都是必不可少的,定義了項目的基本屬性。 這裡有必要對一個不太常用的屬性classifier做一下解釋,因為有時候引用某個jar包,classif ...
  • 本節內容 - 什麼是方法集 - 方法集區分基礎類型T和指針類型*T - 匿名嵌入對方法集的影響 - 方法集調用 ...
  • 語法: mvn install:install-file -Dfile=jar包的位置(參數一) -DgroupId=groupId(參數二) -DartifactId=artifactId(參數三) -Dversion=version(參數四) -Dpackaging=jar 我把“ojdbc-1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...