日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

java中靜態(tài)語句塊、實例代碼塊、構造器方法這3者的調用順序

 chfxh 2017-07-25

1、分析:

1.1、在JVM類加載機制中,有講到:將類加載到JVM當中后,才進行類的初始化。所謂初始化階段,是指:根據(jù)程序員寫的代碼去初始化類變量和其他資源,這句話也可以這么說:初始化階段是執(zhí)行類構造器()方法的過程。()方法是編譯器自動收集類中的所有類變量和靜態(tài)語句塊(static{})中的語句合并而成的。知道這一點很重要,而()方法里面語句的順序由源程序代碼決定。()方法和類實例構造器()方法是不同的。這一點,可以通過調試代碼來驗證,我用的是Mac版本的idea15,在屏幕的最下面一行,可以看到先執(zhí)行()方法,后執(zhí)行()方法。如圖:





1.2、調用完()方法后,才會執(zhí)行類的構造函數(shù)()方法。涉及到構造方法的調用、實例代碼塊的執(zhí)行。同時,實例化幾次類,則進行“實例代碼塊”和“構造器方法”的幾次調用,并且,“實例代碼塊”優(yōu)先于“構造器方法”的調用。



2、驗證代碼:

/** * Created by cxh on 17/07/21. */public class Main { //實例化代碼塊.每次生成類實例,都會執(zhí)行.并且,實例化代碼塊的執(zhí)行 優(yōu)先于 構造器. { System.out.println('blockA'); } //靜態(tài)語句塊,在類初始化時,僅僅執(zhí)行一次. static{ System.out.println('blockB'); } //類實例 public static Main t1 = new Main(); //構造器方法 Main(){ System.out.println('constructor'); } public static void main(String[] args) { //類實例 Main t2 = new Main(); }}

輸出結果:

blockBblockAconstructorblockAconstructorProcess finished with exit code 0


3、說明:

3.1、名字上的區(qū)分

()方法的名字:類構造器方法

()方法的名字:  實例構造器方法  or  類的構造函數(shù)

3.2、說一下()方法

3.2.1、()方法中的內容由編譯器自動收集類中的2類東西組成:類變量和靜態(tài)語句塊中的語句。在()方法中各個語句的排列順序和java代碼順序保持一致。這樣的順序也決定了:靜態(tài)語句塊中只能訪問靜態(tài)語句塊之前的靜態(tài)變量;定義在它后面的變量,是不能被訪問的,但是可以為其賦值。如:


修改后代碼:

/** * Created by cxh on 17/07/21. */public class Main { static int a=0; static{ System.out.println('blockB'); System.out.println(a); //System.out.println(b); //報錯:Illegal forward reference b=3; } static int b=1; public static void main(String[] args) { //類實例 Main t2 = new Main(); System.out.println('b:'+b); System.out.println('a:'+a); }}


運行結果:
blockB0b:1a:0

3.2.2、()方法與類的構造函數(shù)(or 說實例構造器方法()方法)不同。它不需要顯示的調用父類構造器,虛擬機會保證在子類的()方法執(zhí)行之前,父類的()已經之行完畢。因此在虛擬機中第一個被執(zhí)行的()方法的類肯定是java.lang.Object。

3.2.3、由于父類的()方法先執(zhí)行,也就意味著父類中定義的靜態(tài)語句塊     先于    子類的變量賦值操作。

3.2.4、()對于類和接口來說,并不是必需的。因為如果一個類中沒有靜態(tài)語句塊,也沒有對類變量的賦值操作,那么編譯器可以不為這個類生成()方法。

3.2.5、接口中不能使用靜態(tài)語句塊,但仍然有變量初始化的賦值操作。因此接口和類一樣都會生成()。只有當父接口中定義的變量使用是,父接口才會初始化。另外,接口的實現(xiàn)類在初始化時,也一樣不會執(zhí)行接口的()方法。

3.2.6、虛擬機會保證一個類的()方法在多線程環(huán)境中被正確加鎖、同步,如果多個線程同時去初始化一個類,那么只會有一個線程去執(zhí)行這個類的()方法,其他線程都需要阻塞等待,直到活動線程執(zhí)行()方法完畢。如果在一個類中的()方法有很耗時的操作,就可能造成多個線程阻塞,在實際應用中,這種阻塞是很隱蔽的。

注:需要注意的是,其他線程雖然會被阻塞,但如果執(zhí)行()方法的那條線程退出()方法后,其他線程不會再執(zhí)行()方法。同一個類加載器,一個類型只會初始化一次。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多