亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

java語(yǔ)言

Java類和對(duì)象的初始化順序

時(shí)間:2024-09-13 05:04:03 java語(yǔ)言 我要投稿
  • 相關(guān)推薦

Java類和對(duì)象的初始化順序

  在Java中,類裝載器把一個(gè)類裝入Java虛擬機(jī)中,要經(jīng)過(guò)三個(gè)步驟來(lái)完成:裝載、鏈接和初始化,其中鏈接又可以分成校驗(yàn)、準(zhǔn)備和解析三步,除了解析外,其它步驟是嚴(yán)格按照順序完成的。下面一起來(lái)看看吧!

  類裝載步驟

  在Java中,類裝載器把一個(gè)類裝入Java虛擬機(jī)中,要經(jīng)過(guò)三個(gè)步驟來(lái)完成:裝載、鏈接和初始化,其中鏈接又可以分成校驗(yàn)、準(zhǔn)備和解析三步,除了解析外,其它步驟是嚴(yán)格按照順序完成的,各個(gè)步驟的主要工作如下:

  裝載:查找和導(dǎo)入類或接口的二進(jìn)制數(shù)據(jù);

  鏈接:執(zhí)行下面的校驗(yàn)、準(zhǔn)備和解析步驟,其中解析步驟是可以選擇的;

  校驗(yàn):檢查導(dǎo)入類或接口的二進(jìn)制數(shù)據(jù)的正確性;

  準(zhǔn)備:給類的靜態(tài)變量分配并初始化存儲(chǔ)空間;

  解析:將符號(hào)引用轉(zhuǎn)成直接引用;

  初始化:激活類的靜態(tài)變量的初始化Java代碼和靜態(tài)Java代碼塊。

  其中 初始化(initialization)包含兩部分:

  1.類的初始化(initialization class & interface)

  2.對(duì)象的創(chuàng)建(creation of new class instances)。

  因?yàn)轭惖某跏蓟鋵?shí)是類加載(loading of classes)的最后一步,所以很多書中把它歸結(jié)為“對(duì)象的創(chuàng)建”的第一步。其實(shí)只是看問(wèn)題的角度不同而已。為了更清楚的理解,這里還是分開來(lái)。

  順序:

  因?yàn)轭惖募虞d肯定是第一步的,所以類的初始化在前。大體的初始化順序是:

  類初始化 -> 子類構(gòu)造函數(shù) -> 父類構(gòu)造函數(shù) -> 實(shí)例化成員變量 -> 繼續(xù)執(zhí)行子類構(gòu)造函數(shù)的語(yǔ)句

  下面結(jié)合例子,具體解釋一下。

  1. 類的初始化(Initialization classes and interfaces)

  其實(shí)很簡(jiǎn)單,具體來(lái)說(shuō)有:

  (a)初始化類(initialization of class),是指初始化static field 和執(zhí)行static初始化塊。

  public class Demo{ //初始化static field, //其中= "initialization static field"又叫做static field initializer private static String str = "initialization static field"; //初始化塊,又叫做static initializer,或 static initialization block static { System.out.println("This is static initializer"); } }

  btw,有些書上提到static initializer 和 static field initializer 的概念,與之對(duì)應(yīng)的還有 instance initializer 和 instance variable initializer。例子中的注釋已經(jīng)解釋了其含義。

  (b)初始化接口(initialization of interface),是指初始化定義在該interface中的field。

  *注意*

  1. initialization classes 時(shí),該class的superclass 將首先被初始化,但其實(shí)現(xiàn)的interface則不會(huì)。

  initialization classes 時(shí),該class的superclass,以及superlcass的superclass 會(huì)首先被遞歸地初始化,一直到j(luò)ava.lang.Object為止。但initialiazation interface的時(shí)候,卻不需如此,只會(huì)初始化該interface本身。

  2. 對(duì)于由引用類變量(class field)所引發(fā)的初始化,只會(huì)初始化真正定義該field的class。

  3. 如果一個(gè)static field是編譯時(shí)常量(compile-time constant),則對(duì)它的引用不會(huì)引起定義它的類的初始化。

  為了幫助理解最后兩點(diǎn),請(qǐng)?jiān)囋嚳聪旅娴睦樱?/p>

  Initialization類

  public class Initialization { static { System.out.println("Initialization Main class"); } public static void main(String[] args) { System.out.println(Sub.y); System.out.println(Sub.x); System.out.println(Sub.z); } }

  Sub類

  public class Sub extends Super { public static final int y = 2005; public static int z; static { System.out.println("Initialization Sub"); } }

  Super類

  public class Super { public static int x = 2006; static { System.out.println("Initialization Super"); } }

  輸入結(jié)果

  Initialization Main class

  2005

  Initialization Super

  2006

  Initialization Sub

  從這個(gè)結(jié)果可以看到,

  static塊在類中會(huì)先執(zhí)行;(實(shí)際上是先加載static成員變量,然后是static代碼塊)

  static 的final變量不會(huì)引起類的初始化;

  子類Sub引用父類Super里面的變量,就會(huì)引起父類的初始化,但不會(huì)引起子類的初始化;

  static的成員變量也有默認(rèn)值。

  2. 對(duì)象的創(chuàng)建(creation of new class instances)

  看例子來(lái)說(shuō)明:

  InitializationOrder類

  public class InitializationOrder { public static void main(String[] args) { SubClass sb = new SubClass(); } }

  SuperClass類

  public class SuperClass{ static { System.out.println("SuperClass static"); } SuperClass(String str){ System.out.println(str); } }

  Interface類

  interface Interface{ static SuperClass su = new SuperClass("Interface new SuperClass"); }

  SubClass類

  public class SubClass extends SuperClass implements Interface{ static { System.out.println("SubClass static"); } private SuperClass su = new SuperClass("initialization variable"); SubClass() { super("super"); new SuperClass("new SuperClass"); } }

  輸出結(jié)果

  SuperClass static

  SubClass static

  super

  initialization variable

  new SuperClass

  解釋一下:

  1) Java虛擬機(jī)要執(zhí)行InitializationOrder類中的static 方法main(),這引起了類的初始化。開始初始化InitializationOrder類。具體的步驟略去不說(shuō)。

  2) InitializationOrder類初始化完畢后,開始執(zhí)行main()方法。語(yǔ)句SubClass sb = new SubClass()將創(chuàng)建一個(gè)SubClass對(duì)象。加載類SubClass后對(duì)其進(jìn)行類初始化,因?yàn)镾ubclass有一個(gè)父類SuperClass,所以先初始化SuperClass類。于是看到輸出“SuperClass static”。

  3) SuperClass類初始化完畢后,開始初始化SubClass類,輸出“SubClass static”。

  4) 至此,類的加載工作全部完成。開始進(jìn)入創(chuàng)建SubClass的對(duì)象過(guò)程。先為SubClass類和其父類SuperClass類分配內(nèi)存空間,這時(shí)Super su 被賦值為null。

  5) 執(zhí)行構(gòu)造函數(shù)SubClass(),執(zhí)行super(), 調(diào)用父類的構(gòu)造函數(shù),輸出“super”。

  6) 初始化SubClass類的成員變量su,輸出“initialization variable”。

  7) 繼續(xù)執(zhí)行構(gòu)造函數(shù)的剩余部分,執(zhí)行new SuperClass("new SuperClass"),輸出“new SuperClass”,這時(shí)Super su 被賦值新建對(duì)象的引用。

  8) 而SubClass雖然實(shí)現(xiàn)了接口Interface,但是初始化它的時(shí)候并不會(huì)引起接口的初始化,所以接口Interface中的static SuperClass su = new SuperClass("Interface new SuperClass")自始至終都沒(méi)有被執(zhí)行到。

  所以對(duì)象的創(chuàng)建,具體步驟如下:

  (1) 所有的成員變量—包括該類,及它的父類中的成員變量--被分配內(nèi)存空間,并賦予默認(rèn)值。(這里是第一次初始化成員變量)

  (2) 為所調(diào)用的構(gòu)造函數(shù)初始化其參數(shù)變量。(如果有參數(shù))

  (3) 如果在構(gòu)造函數(shù)中用this 調(diào)用了同類中的其他構(gòu)造函數(shù),則按照步驟(2)~(6)去處理被調(diào)用到的構(gòu)造函數(shù)。

  (4) 如果在構(gòu)造函數(shù)中用super調(diào)用了其父類的構(gòu)造函數(shù),則按照步驟(2)~(6)去處理被調(diào)用到的父類構(gòu)造函數(shù)。

  (5) 按照書寫順序,執(zhí)行instance initializer 和 instance variable initializer來(lái)初始化成員變量。(這里是第二次初始化成員變量)

  (6) 按照書寫順序,執(zhí)行構(gòu)造函數(shù)的其余部分。

  總結(jié):

  從類的初始化和對(duì)象的創(chuàng)建步驟,可以知道,一個(gè)類是先初始化static的變量和static句塊,然后在分配該類以及父類的成員變量的內(nèi)存空間,賦予默認(rèn)值,然后開始調(diào)用構(gòu)造函數(shù)。而子類和父類之間,則先初始化和創(chuàng)建父類,然后在初始化和創(chuàng)建子類的。

【Java類和對(duì)象的初始化順序】相關(guān)文章:

關(guān)于Java類的定義以及執(zhí)行順序?qū)W習(xí)教程10-17

精選Java初始化和回收的面試題9個(gè)08-29

Java中對(duì)象和引用的具體區(qū)別05-18

理解java和python類變量10-06

Java的類07-19

PHP編程:類和對(duì)象、方法調(diào)用09-26

java面向?qū)ο缶幊讨v解06-18

s("download_bottom");