java调用类中的静态变量时类中静态代码块什么情况会执行以及类的初始化问题?
類從被加載到虛擬機(jī)內(nèi)存中開始,到卸載出內(nèi)存為止,它的整個生命周期包括:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載七個階段。
類初始化是類加載過程的最后一個階段,到初始化階段,才真正開始執(zhí)行類中的Java程序代碼。虛擬機(jī)規(guī)范嚴(yán)格規(guī)定了有且只有5種情況必須立即對類進(jìn)行初始化:
第一種:遇到new、getstatic、putstatic、invokestatic這四條字節(jié)碼指令時,如果類還沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。生成這四條指令最常見的Java代碼場景是:使用new關(guān)鍵字實(shí)例化對象時、讀取或設(shè)置一個類的靜態(tài)字段(static)時(被static修飾又被final修飾的,已在編譯期把結(jié)果放入常量池的靜態(tài)字段除外)、以及調(diào)用一個類的靜態(tài)方法時。
第二種:使用Java.lang.refect包的方法對類進(jìn)行反射調(diào)用時,如果類還沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
第三種:當(dāng)初始化一個類的時候,如果發(fā)現(xiàn)其父類還沒有進(jìn)行初始化,則需要先觸發(fā)其父類的初始化。
第四種:當(dāng)虛擬機(jī)啟動時,用戶需要指定一個要執(zhí)行的主類,虛擬機(jī)會先執(zhí)行該主類。
第五種:當(dāng)使用JDK1.5支持時,如果一個java.langl.incoke.MethodHandle實(shí)例最后的解析結(jié)果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且這個方法句柄所對應(yīng)的類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始
執(zhí)行代碼:
package com.spring.partise;import java.util.Random;class A{static final int numA = Main.rand.nextInt(100);static{System.out.println("I am A");} } class B{static final int numB = 2;static{System.out.println("I am B");} } class C{static int numC = 3;static{System.out.println("I am C");} } public class Main {static Random rand = new Random();public static void main(String[] args) throws Exception {System.out.println("---------------------------");System.out.println(A.numA);//會執(zhí)行static中的方法System.out.println("---------------------------");System.out.println(B.numB);//不會執(zhí)行static中的方法System.out.println("---------------------------");System.out.println(C.numC);} }執(zhí)行結(jié)果:
--------------------------- I am A 22 --------------------------- 2 --------------------------- I am C 3總結(jié):如果一個static final值是“編譯期常量”,就像static final int numB = 2;那樣,那么這個值不需要對B類進(jìn)行初始化就可以讀取。但是,如果只是將一個域設(shè)置為static和final的,那不一足以確保這種行為,例如,對static final int numA = Main.rand.nextInt(100);的訪問將強(qiáng)制進(jìn)行類的初始化,因?yàn)樗皇且粋€編譯期常量。
如果一個static 域不是final,那么在對它訪問時,總是要求在它被讀取之前,要先進(jìn)行鏈接(為這個域分配存儲空間)和初始化(初始化該存儲空間)就像static int numC = 3;那樣!!!
總結(jié)
以上是生活随笔為你收集整理的java调用类中的静态变量时类中静态代码块什么情况会执行以及类的初始化问题?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jetty优秀文章
- 下一篇: Jupyter notebook应用总结