Java類的載入的一個小問題
前言
之前寫了一篇文章專門介紹了一下類的載入和對象的創建流程,然後收到了一個博友的疑問,覺得蠻好的,在這裡和大家分享下。
疑問類在載入的時候,是不是就可以被實例化?
1 public class Test3 {
2 public static Test3 t = new Test3;
3
4 {
5 System.out.println("blockA");
6 }
7
8 static {
9 System.out.println("blockB");
10 }
11
12 public static void main(String[] args) {
13 Test3 t1 = new Test3;
14 }
15 }
運行結果
1 blockA
2 blockB
3 blockA
你對結果有疑問嗎?和你認為的一樣嗎?
分析其實這個問題如果理解了類的載入和對象的創建流程,其實很容易理解的。
類的載入簡單的流程是:
1. 先載入靜態內容:靜態成員變數,靜態代碼塊,靜態方法。(按書寫順序載入)
- 靜態成員變數默認初始化,完成之後,靜態成員變數顯示初始化。
- 執行靜態的代碼塊內容。先執行父類的靜態代碼塊,再執行子類的靜態代碼塊。
2. 靜態內容載入完成之後,再載入非靜態內容。
3. 所有的靜態內容和非靜態內容載入完成之後,類載入完成。
4. 類載入完成之後可以執行程序中具體的對象創建和代碼。
對象的創建1.給對象分配內存空間,其實就是分配內存地址。
2.對類中的的非靜態的成員變數開始默認初始化。
3.載入對應的構造方法,執行隱式三步
①有個隱式的super; ②顯示初始化(給所有的非靜態的成員變數) ③執行非靜態構造代碼塊 之後才開始執行本類的構造方法中的代碼
4.對象創建完成
解答針對上面的代碼示例,我們可以分析下列印結果:
1. 執行main方法,由於JVM中之前沒有Test3.class信息,因此需要載入類Test3的Class文件到JVM中。
2. 根據類的載入原理,先載入靜態內容,再載入非靜態內容,因此首先載入的就是
public static Test3 t = new Test3;
這是一個靜態實例化的代碼,根據對象的創建流程,一步一步的執行,會在載入對應的構造方法時,執行隱式三步:Test3無顯示繼承的父類(默認繼承超類Object),無非靜態的成員變數,有非靜態的構造代碼塊 --> 執行非靜態的構造代碼塊,列印 "blockA"。
3. 第一個static 載入完成之後,繼續往下執行其他的static,執行靜態代碼塊,列印 "blockB"。
4. 類的載入完成
5. 回來執行main方法中的 Test3 t1 = new Test3; 執行隱式三步,得到列印結果:"blockA"。
因此最終的輸出結果為:
1 blockA
2 blockB
3 blockA


※EF Core學習Code First
※多線程和非同步編程示例和實踐-踩過的坑
※cordova 插件開發
TAG:達人科技 |
※cocos2dx實現載入頁loading頁,載入進度條和載入字樣(附代碼)
※Python3.7中一種懶載入的方式
※overlord,骨傲天的三大個人秀,每場都足以載入異世界之巔
※Bitmap 的高效載入
※遊戲啟動載入大比拼,iPhoneX要甩三星Note9三條街了
※你的 Vans Sk8-Hi 正在載入中……
※JasperLoader:主攻義大利的惡意軟體載入器
※React loadable 按需載入 個人使用記錄
※Linux命令備忘錄:mount用於載入文件系統到指定的載入點
※django載入css文件和圖片
※論APP載入速度,看小米8如何零封vivo X23
※黑產代碼解密-利用canvas載入代碼
※數據載入過慢?這裡有一份TensorFlow加速指南
※Android圖片載入框架最全解析二,從源碼的角度理解Glide的執行流程
※下一代Playstation對比PS4 pro 載入時間省90%
※VasSonic源碼之並行載入
※Unity發布WebGL時如何修改/刪除默認的Logo和載入進度條
※Spring源碼閱讀——Bean的載入和獲取過程
※Windows 10 Mail更新:可載入外部伺服器上的圖片
※Bungie:將在近期改善《命運2》載入時間過長的問題