摘要:想來(lái)想去先來(lái)一題比較好輸出結(jié)果分析類(lèi)初始化順序父類(lèi)靜態(tài)變量父類(lèi)靜態(tài)代碼塊子類(lèi)靜態(tài)代碼塊父類(lèi)非靜態(tài)變量父類(lèi)非靜態(tài)代碼塊父類(lèi)構(gòu)造函數(shù)子類(lèi)非靜態(tài)變量子類(lèi)非靜態(tài)代碼塊子類(lèi)構(gòu)造函數(shù)非靜態(tài)代碼塊輸出結(jié)果順序非靜態(tài)代碼塊被編譯器拷貝到了構(gòu)造塊內(nèi)所以稱(chēng)
static block and non-static block(constructor block)
[toc]
想來(lái)想去,先來(lái)一題比較好public class Foo { public static void main(String[] args) { Baz.testAsserts(); Baz.testAsserts(); // Will execute after Baz is initialized. } } class Bar { static { Baz.testAsserts(); // Will execute before Baz is initialized! } } class Baz extends Bar { static int x = 1; static void testAsserts() { System.out.println("x is " + x); x=x+2; } }
輸出結(jié)果
x is 0
x is 1
x is 3
分析
Java類(lèi)初始化順序Invoking Baz.testAsserts() cause Baz to be initialized
default value int x=0;
Before Baz initialize , Bar must be initialized
Bar"s static initializer again invoking Baz.testAsserts()
so x is 0 , then x+2 , x=2
go on initializing Baz , init x = 1;
Invoking Baz.testAsserts() x = 1 , so x is 1;
父類(lèi)靜態(tài)變量 ——>父類(lèi)靜態(tài)代碼塊——>子類(lèi)靜態(tài)代碼塊——>父類(lèi)非靜態(tài)變量 ——>非靜態(tài)代碼塊 non-static block(constructor block)
父類(lèi)非靜態(tài)代碼塊——>父類(lèi)構(gòu)造函數(shù) ——>子類(lèi)非靜態(tài)變量——>子類(lèi)非靜態(tài)代碼塊——>
子類(lèi)構(gòu)造函數(shù)
class A { int x ; //block num 1 { x = 1; System.out.println("block num 1, x is " + x); } A() { x = 3; System.out.println("constructor block x is " + x); } //block num 2 { x = 2; System.out.println("block num 2, x is " + x); } } public class Non_staticBlock { public static void main(String[] args) { String newLine = System.getProperty("line.separator"); System.out.println("====first time instantiate ====" + newLine); new A(); System.out.println(" ====second time instantiate ====" + newLine); new A(); } }
輸出結(jié)果、順序
====first time instantiate ====block num 1, x is 1
block num 2, x is 2
constructor x is 3====second time instantiate ====
block num 1, x is 1
block num 2, x is 2
constructor x is 3
非靜態(tài)代碼塊被java編譯器拷貝到了構(gòu)造塊內(nèi),所以稱(chēng)為"constructor block"也是可以的,所以每次 new 構(gòu)造函數(shù)也都執(zhí)行
.class 文件如下, 非靜態(tài)代碼塊被java編譯器拷貝到了構(gòu)造塊內(nèi).
class A { int x = 1; A() { System.out.println("block num 1, x is " + this.x); this.x = 2; System.out.println("block num 2, x is " + this.x); this.x = 3; System.out.println("constructor x is " + this.x); } }靜態(tài)代碼塊 static block
class AA { AA() { x = 3; System.out.println("constructor x is " + x); } static int x = 1; //block num 1 static { System.out.println("static block num 1 , x is " + x); } //block num 2 static { x = 2; System.out.println("static block num 2 , x is " + x); } static void print() { System.out.println("static method"); } } public class StaticBlock { static { System.out.println("==== first ===="); } public static void main(String[] args) { String newLine = System.getProperty("line.separator"); System.out.println("====AA class init ====" + newLine); // class init AA.print(); System.out.println(" ====fisrt time instantiate AA====" + newLine); new AA(); System.out.println(" ====sencond time instantiate AA====" + newLine); new AA(); } }
輸出結(jié)果、順序
==== first ====
====AA class init ====static block num 1 , x is 1
static block num 2 , x is 2
static method
==== first time instantiate AA ====constructor x is 3
==== second time instantiate AA ====
constructor x is 3
由于JVM在加載類(lèi)時(shí)會(huì)執(zhí)行靜態(tài)代碼塊,且只會(huì)執(zhí)行一次. 本例靜態(tài)引用AA.print(); 觸發(fā)類(lèi)初始化
靜態(tài)代碼塊先于主方法執(zhí)行,本例優(yōu)先打印first
更多內(nèi)容搜索jvm類(lèi)加載
.class 文件如下
class AA { static int x = 1; AA() { x = 3; System.out.println("constructor x is " + x); } static void print() { System.out.println("static method"); } static { System.out.println("static block num 1 , x is " + x); x = 2; System.out.println("static block num 2 , x is " + x); } }聯(lián)合看一下
class AAA { int x; //block num 1 { x = 1; System.out.println("non-static block num 1 x is " + x); } AAA() { x = 3; System.out.println("constructor x is " + x); } //block num 2 { x = 2; System.out.println("non-static block num 2 x is " + x); } // The static block only gets called once,when the class itself is initialized, // no matter how many objects of that type you create static { System.out.println("static block"); } //Gets called every time an instance of the class is constructed. //the non-static block is actually copied by the Java compiler into every constructor the class has (source). //So it is still the constructor"s job to initialize fields. //to understand "actually " , find the result in the .class file of A.class { System.out.println("non-static block"); } } public class BlockSample { public static void main(String[] args) { String newLine = System.getProperty("line.separator"); System.out.println("====first time instantiate AAA ====" + newLine); new AAA(); System.out.println(" ====second time instantiate AAA ====" + newLine); new AAA(); } }
輸出結(jié)果、順序
====first time instantiate AAA ====static block
non-static block num 1 x is 1
non-static block num 2 x is 2
non-static block
constructor x is 3====second time instantiate AAA ====
non-static block num 1 x is 1
non-static block num 2 x is 2
non-static block
constructor x is 3
.class 文件
class AAA { int x = 1; AAA() { System.out.println("non-static block num 1 x is " + this.x); this.x = 2; System.out.println("non-static block num 2 x is " + this.x); System.out.println("non-static block"); this.x = 3; System.out.println("constructor x is " + this.x); } static { System.out.println("static block"); } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/68402.html
摘要:八種基本數(shù)據(jù)類(lèi)型數(shù)組定義數(shù)組元素類(lèi)型數(shù)組名元素類(lèi)型元素個(gè)數(shù)和數(shù)組長(zhǎng)度元素類(lèi)型數(shù)組名元素類(lèi)型元素元素元素元素內(nèi)存的劃分寄存器本地方法區(qū)方法區(qū)棧內(nèi)存存儲(chǔ)局部變量變量所屬作用域一旦結(jié)束變量自動(dòng)釋放方法進(jìn)棧局部變量屬于方法所以方法要先進(jìn)棧堆內(nèi)存存儲(chǔ) 八種基本數(shù)據(jù)類(lèi)型 byte short int long boolean char float double JAVA數(shù)組 定義數(shù)組 元...
摘要:對(duì)子類(lèi)成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類(lèi)構(gòu)造函數(shù)的其余部分。參考類(lèi)的初始化順序引了大半類(lèi)加載的時(shí)機(jī) jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card table數(shù)據(jù)結(jié)構(gòu) Java類(lèi)初始化順序 Java對(duì)象結(jié)構(gòu)及大小計(jì)算 Java的類(lèi)加載機(jī)制 Java對(duì)象分配簡(jiǎn)要流程 年老...
這是網(wǎng)易2015校招Java面試題,直接上題目。 題目 package com.mousycoder.staticTest; public class HelloB extends HelloA { public HelloB() { System.out.println(HelloB); } { System.out.println(I...
摘要:看到的只是,而由泛型附加的類(lèi)型信息對(duì)來(lái)說(shuō)是不可見(jiàn)的。然后再加載執(zhí)行類(lèi)的靜態(tài)變量以及靜態(tài)語(yǔ)句塊。接口中基本數(shù)據(jù)類(lèi)型為而抽類(lèi)象不是的。本地方法接口主要是調(diào)用或?qū)崿F(xiàn)的本地方法及返回結(jié)果。用戶(hù)自定義類(lèi)加載器,在程序運(yùn)行期間,通過(guò)的子類(lèi)動(dòng)態(tài)加載。 編譯機(jī)制 編譯主要是把?.Java文件轉(zhuǎn)換為 .class 文件。其中轉(zhuǎn)換后的 .class 文件就包含了元數(shù)據(jù),方法信息等一些信息。比如說(shuō)元數(shù)據(jù)就...
摘要:沒(méi)有關(guān)鍵字修飾的如實(shí)例變量非靜態(tài)變量非靜態(tài)代碼塊初始化實(shí)際上是會(huì)被提取到類(lèi)的構(gòu)造器中被執(zhí)行的,但是會(huì)比類(lèi)構(gòu)造器中的代碼塊優(yōu)先執(zhí)行到,非靜態(tài)實(shí)例變量非靜態(tài)代碼塊的地位是相等的,它們將按順序被執(zhí)行。 閱讀原文:Java代碼執(zhí)行順序 程序中代碼執(zhí)行的順序非常重要,稍有不慎便會(huì)是程序運(yùn)行出錯(cuò),那么我將結(jié)合實(shí)例來(lái)分析代碼中的執(zhí)行。 名詞解釋 首先了解幾個(gè)名詞: 非靜態(tài)代碼塊 直接由 { } 包起...
閱讀 1335·2021-10-14 09:50
閱讀 1627·2019-08-30 15:54
閱讀 1090·2019-08-30 11:22
閱讀 2987·2019-08-30 10:50
閱讀 1873·2019-08-29 18:39
閱讀 3125·2019-08-29 13:07
閱讀 2132·2019-08-28 17:54
閱讀 800·2019-08-26 17:44