參考自:[https://blog.csdn.net/ns_code/article/details/17881581]
重點(diǎn)
- 程序均在內(nèi)存中執(zhí)行,變量(方法)只有存放于內(nèi)存中時(shí),才能被訪(fǎng)問(wèn)
- 類(lèi)的靜態(tài)成員(變量或方法)屬于類(lèi)本身,在類(lèi)加載的時(shí)候就會(huì)分配內(nèi)存,可以通過(guò)類(lèi)名直接去訪(fǎng)問(wèn)。
- 非靜態(tài)成員(變量和方法)屬于類(lèi)的對(duì)象,只有在類(lèi)的對(duì)象產(chǎn)生時(shí)(創(chuàng)建實(shí)例-new)才會(huì)分配內(nèi)存,然后通過(guò)實(shí)例去訪(fǎng)問(wèn)。
類(lèi)加載過(guò)程
類(lèi)從被加載到虛擬機(jī)中開(kāi)始,到卸載出內(nèi)存為止,整個(gè)生命周期包括:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載七個(gè)階段。如圖所示:

Image.png
其中類(lèi)加載的過(guò)程中包括了加載、驗(yàn)證、準(zhǔn)備、解析、初始化五個(gè)階段。
這五個(gè)階段除了解析其他四個(gè)階段發(fā)生的順序是確定的,解析階段在某些情況下考研在初始化階段之后,是為了支持Java語(yǔ)言的運(yùn)行時(shí)綁定(也稱(chēng)為動(dòng)態(tài)綁定或晚期綁定)。
Note:這幾個(gè)階段是順序開(kāi)始,并不是順序進(jìn)行或順序完成。通常是互相交叉混合進(jìn)行,在一個(gè)階段的執(zhí)行過(guò)程中調(diào)用或激活另一個(gè)階段。
Java中綁定:把一個(gè)方法的調(diào)用與方法所在的類(lèi)關(guān)聯(lián)起來(lái),分為靜態(tài)和動(dòng)態(tài)綁定。
- 靜態(tài)綁定:前期綁定。在程序執(zhí)行前已經(jīng)綁定。java中只有final、static、private和構(gòu)造方法是前期綁定的。
- 動(dòng)態(tài)綁定:即晚期綁定或運(yùn)行綁定。在java中,幾乎所有的方法都是后期綁定的。
準(zhǔn)備階段
準(zhǔn)備階段是正式為類(lèi)變量分配內(nèi)存并設(shè)置類(lèi)變量初始值的階段,這些內(nèi)存都將在方法區(qū)中分配。對(duì)于該階段有以下幾點(diǎn)需要注意:
- 這時(shí)候進(jìn)行內(nèi)存分配的僅包括類(lèi)變量(static),而不包括實(shí)例變量,實(shí)例變量會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一塊分配在Java堆中。
- 這里所設(shè)置的初始值通常情況下是數(shù)據(jù)類(lèi)型默認(rèn)的零值(如0、0L、null、false等),而不是被在Java代碼中被顯式地賦予的值。
假設(shè)一個(gè)類(lèi)別量定義為:
public static int value = 3
那么變量value在準(zhǔn)備階段過(guò)后的初始值為0,而不是3,因?yàn)檫@個(gè)時(shí)候未執(zhí)行任何java方法,而把value賦值為3的putstatic指令是在程序編譯后,存放于類(lèi)構(gòu)造器<clinit>()方法之中的,所以把value賦值為3的動(dòng)作將在初始化階段才會(huì)執(zhí)行。
Java中所有基本數(shù)據(jù)類(lèi)型以及reference類(lèi)型的默認(rèn)零值:
| 數(shù)據(jù)類(lèi)型 | 默認(rèn)零值 |
|---|---|
| int | 0 |
| long | 0L |
Note:
- 對(duì)基本數(shù)據(jù)類(lèi)型來(lái)說(shuō),對(duì)于類(lèi)變量(static)和全局變量,如果不顯式地對(duì)其賦值而直接使用,則系統(tǒng)會(huì)為其賦予默認(rèn)的零值,而對(duì)于局部變量來(lái)說(shuō),在使用前必須顯式地為其賦值,否則編譯時(shí)不通過(guò)。
- 對(duì)于同時(shí)被static和final修飾的常量,必須在聲明的時(shí)候就為其顯式地賦值,否則編譯時(shí)不通過(guò);而只被final修飾的常量則既可以在聲明時(shí)顯式地為其賦值,也可以在類(lèi)初始化時(shí)顯式地為其賦值,總之,在使用前必須為其顯式地賦值,系統(tǒng)不會(huì)為其賦予默認(rèn)零值。
- 對(duì)于引用數(shù)據(jù)類(lèi)型reference來(lái)說(shuō),如數(shù)組引用、對(duì)象引用等,如果沒(méi)有對(duì)其進(jìn)行顯式地賦值而直接使用,系統(tǒng)都會(huì)為其賦予默認(rèn)的零值,即null。
- 如果在數(shù)組初始化時(shí)沒(méi)有對(duì)數(shù)組中的各元素賦值,那么其中的元素將根據(jù)對(duì)應(yīng)的數(shù)據(jù)類(lèi)型而被賦予默認(rèn)的零值。