初始化的順序是先“靜態”,(如果它們尚未因前面的對象建立過程而被初始化),後“非靜態”。 具體的建立過程: 1.當首次建立某個類對象的時候,或者該類的靜態方法/靜態域首次被訪問時,Java解譯器必須尋找該類的路徑,以定位該類的class檔案。 2.然後載入該class(建立一個Class對象),有關靜態初始化的動作都會執行。靜態初始化只在Class對象首次載入的時候進行一次。 例如:按照出現順序執行初始化動作 static int n1 = f(1); static{ n3 = f(3); //靜態域的初始化語句不必擔心非法向前引用,但是如果是訪問n3,就會發生非法向前引用的錯誤 System.out.println("println"); } static int n2 = f(2); static int n3; static int f(int i){ System.out.println("n"+i); return i; } 建立對象或者訪問此類的某個靜態域/靜態方法,列印出來: n1 n3 println n2 3.當使用new操作符建立對象的時候,首先將在堆上為待建立的對象分配足夠的儲存空間。 4.這Block Storage空間會被清零,這就自動的將類中所有基本類型資料設定成了預設值(數值和字元是0,布爾是false),而引用則被設定成了null。 5.按出現順序執行所有出現於域(非靜態域)定義處的初始化動作。 6.執行構造器。 運行一下下面的例子就都清楚了。
public class MembersInitializeSequence {
public static void main(String[] args){
Bowl.f();
System.out.println("執行個體化一個Bowl對象");
new Bowl();
System.out.println("再執行個體化一個Bowl對象");
new Bowl();
}
}
class Cup {
Cup(int i){
System.out.println("new Cup("+i+")");
}
}
class Bowl{
Cup c1;
Cup c2 = new Cup(2);
{
c1 = new Cup(1);
}
static{
c4 = new Cup(4);
System.out.println("Bowl中的靜態快,靜態塊只在類載入的時候運行,所以只運行一次");
}
static Cup c3 = new Cup(3);
static Cup c4;
Bowl(){
System.out.println("new Bowl()");
}
static void f(){
System.out.println("Bowl中的靜態方法f()被訪問");
}
}
在類被繼承的情況下,初始化的順序:
1.初始化子類,類載入器在載入它的時候會發現它繼承了另外一個類,類載入器要先把父類載入進來。於是開始載入父類,父類的靜態部分被按順序載入。之後子類的靜態部分被載入。這樣的順序是考慮子類的靜態域可能會依賴父類的靜態域;
2.父類的非靜態部分被載入;
3.子類指定的父類的構造器;
4.子類的非靜態部分被載入;
5.子類構造器的其餘部分。
多個層次的繼承關係,順序也同理。
例:
public class MembersInitializeSequenceEx {
public static void main(String[] args){
// new Cat();
new Tiger();
}
}
class Cat{
int c1 = f1(1);
int f1(int i){
System.out.println("Cat unstatic "+i);
return i;
}
{
System.out.println("Cat unstatic block");
}
static int c2 = f2(2);
static int f2(int i){
System.out.println("Cat static "+i);
return i;
}
static{
System.out.println("Cat static block");
}
public Cat(){
System.out.println("new Cat()");
}
}
class Tiger extends Cat{
int c3 = f1(3);
@Override
int f1(int i){
System.out.println("Tiger unstatic "+i);
return i;
}
{
System.out.println("Tiger unstatic block");
}
static int c4 = f2(4);
static int f2(int i){
System.out.println("Tiger static "+i);
return i;
}
static{
System.out.println("Tiger static block");
}
public Tiger(){
super();
System.out.println("new Tiger()");
}
}