基本初始化過程:
對於乙個簡單類的初始化過程是:
static 修飾的模組(static變數和static 塊) ---> 按照**順序依次執行。
|例項變數 及非static模組---> 按照**順序依次執行。
|建構函式 ---> 執行對應的建構函式。
子類的初始化過程。
父類static修飾的模組
|子類static修飾模組
|父類例項變數和非static塊
|父類對應建構函式。當子類對應建構函式中沒有顯示呼叫時呼叫的是父類預設的建構函式。
|子類例項變數和非static塊
|子類建構函式
class的static模組是唯一的,所以只初始化一次。所有類的例項公用class的static模組。
static模組的初始化條件: ( from: 引用1 )
(1)遇到new、getstatic、putstatic 或 invokestatic這4條位元組碼指令時,如果類還沒初始化,則觸發初始化。對應場景是:new例項化物件時、讀或設定乙個靜態欄位時(被final修飾,已在編譯器把結果放入常量池的靜態字段除外),以及呼叫乙個類的靜態方法時
(2)對類進行反射呼叫時
(3)初始化子類。但父類還沒有初始化時,先觸發父類初始化
(4)當虛擬機器啟動時,需指定乙個需要執行的主類(包含main方法),虛擬機會先初始化該類
關於覆蓋和隱藏
覆蓋:被覆蓋的方法相當於被擦除了,不可恢復(即使型別強制轉換也無法呼叫)。
隱藏:一直儲存的某個位置,等需要的時候可以繼續使用(型別強制轉換後可以呼叫)。
關於父類子類之間的覆蓋和隱藏關係: (from :引用2)
1. 父類的例項變數和類變數能被子類的同名變數隱藏。
2. 父類的靜態方法被子類的同名靜態方法隱藏,父類的例項方法被子類的同名例項方法覆蓋。
3. 不能用子類的靜態方法隱藏父類的例項方法,也不能用子類的例項方法覆蓋父類的靜態方法,否則編譯器會異常。
4. 用final關鍵字修飾的最終方法不能被覆蓋。
5. 變數只能被隱藏不會被覆蓋,子類的例項變數可以隱藏父類的類變數,子類的類變數也可以隱藏父類的例項變數。
涉及的典型情況:
前提:class b extends a
(1) b instanceb = new b();
instanceb的初始化過程如第一部分中:子類的初始化過程。
此時instanceb中實際上有乙個super的全部資訊(除了父類中被覆蓋的例項方法),但是當前的引用是子類的資訊(如果子類中沒有的變數和方法則是從父類繼承來)。
(2)a instancea = new b();
此時父類a的變數和靜態方法會將子類的變數和靜態方法隱藏。instancea此時唯一可能呼叫的子類b的地方就是子類b中覆蓋了父類a中的例項方法。
執行 b instanceb = (b) instancea; 後
此時instanceb相當於 b instanceb = new b();
注意:
(1) 這裡唯一的覆蓋的情況:父類的例項方法被子類的同名例項方法覆蓋。
這裡方法呼叫變數時,實際上是帶有乙個預設的this的。也就是此例項方法中呼叫的是當前class的值。涉及到繼承的情況時,要十分注意super,this的情況。
(2) 在初始化的時候,有兩個階段。第一步是申請空間,第二步是賦值。
具體見:
static的值和final static值在初始化時的區別。(引用1)
子類覆蓋父類例項方法時,呼叫子類的例項方法,而此時子類的例項方法呼叫了子類中的變數(此時static變數已經初始化,但是例項變數並沒有初始化)。(引用2)
這段**來自引用2,如何精煉,如此有趣。值得一看。
class
parent
void add(int y)
}class
child
extends
parent
public
static
void main(string args)
}
引用 1. 類載入機制:
引用 2. 隱藏和覆蓋,以及乙個好例子:
引用 3. 隱藏和覆蓋
引用 4. 基本的初始化過程
Java 父類子類初始化問題
例子 public class test8 extends base public void tellname public void printname public static void main string args class base public void tellname publ...
Java中父類 子類初始化順序
測試結果 父類靜態 塊 子類靜態 塊 父類成員變數初始化parent common block test 父類有參構造方法ppp 子類成員變數初始化son common block test 子類有參構造方法ppp sss 靜態 塊只能生成一次 父類成員變數初始化parent common bloc...
父類,子類初始化 2
載入類時,先父類靜態,再子類靜態,然後是子類中main方法,main方法中如果有生成子類物件的語句,先找到子類建構函式,因為每個子類建構函式裡頭都會有super語句 jdk預設或者自己提供,且預設在建構函式中第一行 則先初始化父類非靜態,然後父類構造,再然後是子類非靜態,子類建構函式 除super之...