靜態變數又稱為類變數,類中被static修飾的成員變數都是靜態變數(類變數)
靜態變數之所以又稱為類變數,是因為靜態變數和類關聯在一起,隨著類的載入而存在於方法區(而不是堆中)
八種基本資料型別(byte、short、int、long、float、double、char、boolean)的靜態變數會在方法區開闢空間,並將對應的值儲存在方法方法區,對於引用型別的靜態變數如果未用new關鍵字為引用型別的靜態變數分配物件(如:static object obj;)那麼物件的引用obj會儲存在方法區中,並為其指定預設值null;若,對於引用型別的靜態變數如果用new關鍵字為引用型別的靜態變數分配物件(如:static person person = new person();),那麼物件的引用person 會儲存在方法區中,並且該物件在堆中的位址也會儲存在方法區中(注意此時靜態變數只儲存了物件的堆位址,而物件本身仍在堆記憶體中);
這個過程還涉及到靜態變數初始化問題:
1.構造**塊:每次建立物件時執行
2.靜態**塊(靜態初始化塊):jvm載入類(載入在執行之前)時執行,靜態**塊(靜態初始化塊)只執行一次
為啥需要靜態初始化塊?
靜態初始化塊主要用來初始化類變數類變數可以在建構函式中初始化為啥還要定義靜態初始化塊呢?
因為,類變數可以通過類名.類變數的形式呼叫,有的時候我們不想為了初始化類變數而建立物件,所以就有了靜態初始化塊。public static b t1 = new b();是類變數及引用(靜態變數及靜態引用)的初始化靜態初始化塊可以在類載入的時候執行一次。避免了了初始化類變數而建立物件
執行順序:類變數及引用(靜態變數及靜態引用)的初始化(預設初始化或「=」顯示賦值)->靜態**塊(靜態初始化塊,堆預設初始化的類變數根據需要重新初始化)->main()->例項變數及引用的初始化->構造**塊->構造方法
例:
public class b
static
public static void main(string args)
}
輸出如下:構造塊構造塊
靜態塊構造塊
原因類變數及引用(靜態變數及靜態引用)的初始化(預設初始化或「=」顯示賦值)優先於靜態初始化塊(靜態塊)執行,接下來靜態初始化塊(靜態塊)按照申明順序執行,,
首先,執行public staticb t1 = newb();該語句建立物件,則會呼叫構造**塊,輸出第乙個構造塊
其次,執行public static b t2 = new b();該語句又建立新物件,則又會呼叫構造**塊,輸出第二個構造塊
接著,再按照靜態**塊申明順序執行下面的靜態**塊:輸出靜態塊
最後,main方法執行,建立物件,輸出static
構造塊
。
堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區
在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區 1.棧由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。棧空間初始化的時候,空間大小就確定了,棧指標指向棧頂 高位址 壓入棧時 棧指標減減,想低位址移動。棧...
堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區
堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區 在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。堆,就是那些由new分配的記憶體塊,他們的...
記憶體儲存 全域性 靜態儲存區 常量儲存區
全域性 靜態儲存區 全域性變數和靜態變數被分配到同一塊記憶體中 常量儲存區 存放的是常量,是不允許修改的。靜態儲存是main函式執行前分配記憶體並初始化 常量儲存是固化在執行檔案上的資料。棧的方向和平台有關,一般來說,windows由高位址向低位址增長,linux相反,但基於linux的第三方系統得...