[转载] Java中静态成员变量,静态代码块,静态内部类何时被初始化?
參考鏈接: Java中的初始化程序塊Initializer Block
關(guān)于這個(gè)問(wèn)題,本文不扯理論,直接上代碼,通過(guò)結(jié)果來(lái)驗(yàn)證結(jié)論,廢話少說(shuō),測(cè)試代碼如下:?
public class StaticTest {
?
? ? public static StaticMember staticMember = new StaticMember();
?
? ? static {
? ? ? ? System.out.println("static code initializer ");
? ? }
?
? ? private static class InnerClass {
? ? ? ? private static StaticTest staticTest = new StaticTest("load from InnerClass");
? ? }
?
? ? public StaticTest() {
? ? }
?
? ? public StaticTest(String a) {
? ? ? ? System.out.println(a);
? ? }
?
? ? public static void f(){
?
? ? }
?
? ? public void d(){
?
? ? }
?
? ? public static void e(){
? ? ? ? InnerClass.staticTest.d();
? ? }
}?
public class StaticMember {
? ? public StaticMember(){
? ? ? ? System.out.println("StaticMember");
? ? }
}?
在StaticTest 測(cè)試類(lèi)中我寫(xiě)了三種靜態(tài)域分別是靜態(tài)成員變量,靜態(tài)代碼塊以及靜態(tài)內(nèi)部類(lèi),下面通過(guò)不同的case測(cè)試上面三種靜態(tài)域何時(shí)被初始化。? 測(cè)試case代碼:?
public class Main {
? ? static boolean flg;
?
? ? public static void main(String[] args) {
?
? ? ? ? /**case1**/
? ? ? ? //不會(huì)執(zhí)行靜態(tài)代碼塊, 靜態(tài)成員變量不會(huì)初始化, 也不會(huì)加載靜態(tài)內(nèi)部類(lèi)
? ? ? ? String simpleName = StaticTest.class.getSimpleName();
?
? ? ? ? /**case2**/
? ? ? ? //會(huì)執(zhí)行靜態(tài)代碼塊, 靜態(tài)成員變量會(huì)初始化, 不會(huì)加載靜態(tài)內(nèi)部類(lèi)
? ? ? ? //輸出 StaticMember
? ? ? ? //? ? static code initializer
? ? ? ? StaticMember staticMember = StaticTest.staticMember;
?
? ? ? ? /**case3**/
? ? ? ? //會(huì)執(zhí)行靜態(tài)代碼塊, 靜態(tài)成員變量會(huì)初始化, 不會(huì)加載靜態(tài)內(nèi)部類(lèi)
? ? ? ? //輸出 StaticMember
? ? ? ? //? ? static code initializer
? ? ? ? new StaticTest();
?
? ? ? ? /**case4**/
? ? ? ? //會(huì)執(zhí)行靜態(tài)代碼塊, 靜態(tài)成員變量會(huì)初始化, 不會(huì)加載靜態(tài)內(nèi)部類(lèi)
? ? ? ? //輸出 StaticMember
? ? ? ? //? ? static code initializer
? ? ? ? StaticTest.f();
?
? ? ? ? /**case5**/
? ? ? ? //不會(huì)執(zhí)行靜態(tài)代碼塊, 靜態(tài)成員變量不會(huì)初始化, 也不會(huì)加載靜態(tài)內(nèi)部類(lèi)
? ? ? ? if (flg) {
? ? ? ? ? ? test();
? ? ? ? }
?
? ? ? ? /**case6**/
? ? ? ? //會(huì)執(zhí)行靜態(tài)代碼塊, 靜態(tài)成員變量會(huì)初始化, 同時(shí)加載靜態(tài)內(nèi)部類(lèi)
? ? ? ? // 輸出:StaticMember
? ? ? ? //? ? ? static code initializer
? ? ? ? //? ? ? load from InnerClass
? ? ? ? StaticTest.e();
? ? }
?
? ? private static void test(){
? ? ? ? StaticTest.f();
? ? ? ? StaticTest.e();
? ? }
?
}?
通過(guò)上面每一種代碼測(cè)試case的輸出結(jié)果,可以得出如下結(jié)論:?
靜態(tài)成員變量和靜態(tài)代碼塊(static{})只有在類(lèi)被調(diào)用的時(shí)候才會(huì)初始化。? 這里是指在運(yùn)行時(shí)真正被使用到才會(huì)被初始化,如果是在編譯時(shí)被使用到,但在運(yùn)行時(shí)沒(méi)有使用到也不會(huì)被初始化,比如上面的case5。靜態(tài)內(nèi)部類(lèi)只有當(dāng)被外部類(lèi)調(diào)用到的時(shí)候才會(huì)初始化。? 這里也是指在運(yùn)行時(shí),也就是說(shuō)不在于你在編輯器中有沒(méi)有寫(xiě)調(diào)用的代碼,而是你寫(xiě)的這段調(diào)用代碼運(yùn)行時(shí)是否會(huì)被真正執(zhí)行到。在只使用了外部類(lèi),但是沒(méi)有使用內(nèi)部類(lèi)的情況下,內(nèi)部類(lèi)里面的東西不會(huì)被初始化。?
關(guān)于case1的情況,直接引用StaticTest.class不會(huì)初始化靜態(tài)變量和靜態(tài)代碼塊,而直接new StaticTest()就會(huì),為什么呢?因?yàn)镴VM在加載類(lèi)的過(guò)程中分為五個(gè)階段:加載、驗(yàn)證、準(zhǔn)備、解析、初始化,StaticTest.class的方式發(fā)生在第一個(gè)階段,這個(gè)階段會(huì)在Java堆中創(chuàng)建java.lang.Class的實(shí)例,而變量和靜態(tài)塊是發(fā)生在最后一個(gè)初始化的階段,具體參考:Java虛擬機(jī) 類(lèi)加載的過(guò)程, Chapter 5. Loading, Linking, and Initializing
總結(jié)
以上是生活随笔為你收集整理的[转载] Java中静态成员变量,静态代码块,静态内部类何时被初始化?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: as模拟器文件夹路径_EGG Switc
- 下一篇: 事物 php,什么是php事务