因為之前對類載入這塊不感興趣,感覺實際應用中又用不到……但工作後發現並非如此,因此學習總結一下——類載入和初始化的過程讓人很繞,有些搞不明白。
首先要明白,類的載入和初始化是兩個過程,同樣也是總是在一起的兩個過程。(菜雞如我一直都很糊塗)。
當我們第一次使用類時,就會觸發類的載入、鏈結、初始化三個過程。(當然也有的說法會有其他過程,這裡我們就簡單一點,只說這三個過程)。
當這三個物件都完成後,我們才能進行建立物件的操作,也就是new的過程,因為建立物件必須用到類的 class 物件。
時機就是第一次使用類時,一般包括三種情況:
下面列出四種可能的情況:
public class a
extends
bpublic
static
void
main
(string[
] args)
}
載入過程,就是建立class物件的過程。
我們都知道類都有乙個class物件,假如有乙個類a,通過a.class就可以獲取這個物件,而實際上class物件就是用來建立物件的。
載入過程,就是建立a的class物件,為後面建立a的物件做準備。
上面的例子我們知道獲取類a的class物件的兩種方法:
這兩種方法有一定的區別,就是a.class只會載入類,不會自動的初始化類。
//3、這次有些特殊,這時候a被載入,但並未被初始化
class aclass
= a.
class
;//4、這時候a被載入並被初始化
class aclass
= class.
forname
("a"
);
類的初始化過程大家就比較熟悉了,是在載入之後,一般都會進行(a.class這種就沒有進行)。
總結一下,初始化順序為:
先初始化父類(如果父類未被初始化)
按順序初始化靜態成員
靜態**塊執行(與上一步優先順序相同,按順序來,但是一般書寫在後面)
呼叫new,建立物件
初始化父類的非靜態成員變數,呼叫父類的建構函式
按順序初始化非靜態成員
非靜態**塊執行(與上一步優先順序相同,按順序來,但是一般書寫在後面)
執行構造器
public class a
extends
b//這塊**和非靜態變數初始化時一起執行a(
)}
如上面類a,它的初始化過程就是。
為 i 賦值0
為 j 賦值0
為 i 賦值1
為 k 賦值0
為 h 賦值0
為 k 賦值1
構造器執行,列印「a構造器執行」
在類的初始化過程中,有一種特殊情況,就是static final修飾的常量。它不需要初始化,就可以直接訪問,因為它是在編譯期就準備好了。
注意,需要滿足兩個條件:
比如:
public
static
final integer i =
0;
此處的 i 是不需要被初始化,就可以直接訪問的。
但是下面:
public
static
final integer j = classinitializarion.rand.
nextint
(1000
);
此處的 j 並不是常量,所以需要初始化之後才能訪問,也就是說,訪問 j 時,會觸發類的初始化。
那上面的類a,用static修飾的成員,也是需要初始化嗎?
public
static integer i =
0;
是的,對 i 訪問時,i 需要先被鏈結,分配儲存空間後,再執行初始化 類初始化過程
class x class y public class z extends x public static void main string args a zyxxb zyxyc yxyzd xyzx解答 靜態變數 靜態 塊 main方法 非靜態變數 塊 構造方法 初始化過程 1.初始化父類中的靜...
類的初始化過程
類的初始化過程中有兩個比較重要的方法 void load void initialize 這兩個方法是自動呼叫的 分類 分類中也是包含 void load 方法和 void initialize 方法的,不同的是 分類的 load 方法在程式啟動的時候也會呼叫,但是如果分類有 initialize ...
類的初始化過程
類的例項化有兩種方法 1.dog d new dog 自動呼叫無參建構函式 2.通過反射 class.forname com.vo.dog newinstance 此種方法只能呼叫無參建構函式,假如函式只有帶參建構函式,就要使用以下的方式 constructor c class.forname co...