1. 程式人生 > 遊戲 >2D魂系風格遊戲《塵埃異變》8月2日推出

2D魂系風格遊戲《塵埃異變》8月2日推出

Java類中程式碼執行順序

靜態程式碼的執行一定先於main方法,靜態程式碼塊和靜態成員變數的執行順序是由程式碼位置決定的,誰寫前面就先執行誰;

如果是非靜態程式碼塊和成員變數,不執行;只有在建立的類的例項物件時,才會執行非靜態程式碼塊和非靜態成員變數;建立多少個物件,就會執行多少次程式碼塊,建立多少個成員變數。非靜態程式碼和非靜態成員變數的執行順序由位置決定,誰寫前面就先執行誰;

如果同時存在非靜態程式碼塊和靜態程式碼塊,以及非靜態成員變數和靜態成員變數,先執行靜態的東西,並且只執行一次,再執行非靜態的東西(建立物件),建立多少個物件就會執行多少次。

package com.jarreet.test;

public class User {

public User(){
System.out.println("User init...");
}
}
package com.jarreet.test;

public class TestExecutionSequence {

// 非靜態成員變數
User user = new User();

// 非靜態程式碼塊
{
System.out.println("code block");
}

// 靜態成員變數
static User staticUser = new User();

// 靜態程式碼塊
static {
System.out.println("static block...");
}

// main函式
public static void main(String[] args) {
System.out.println("main...");
TestExecutionSequence testExecutionSequence1 = new TestExecutionSequence();
TestExecutionSequence testExecutionSequence2 = new TestExecutionSequence();
TestExecutionSequence testExecutionSequence3 = new TestExecutionSequence();
}
}

加入父子類:

package com.jarreet.test;

public class Stub {
public Stub(String str){
System.out.println(str + "object created");
}
}
package com.jarreet.test;

public class Parent {

static Stub parentStaticStub = new Stub("parent static object-");

static {
System.out.println("parent static code excute");
}

Stub parentStub = new Stub("parent object-");

{
System.out.println("parent code excute");
}


Stub stub;
public Parent(){
System.out.println("parent constructor excute");
stub = new Stub("parent constructor created object-");
}

public void sayHello(){
System.out.println("hello from parent");
}
}
package com.jarreet.test;

public class Child extends Parent{

static Stub childStaticStub = new Stub("child static object-");

static {
System.out.println("child static code excute");
}

Stub childStub = new Stub("child object-");

{
System.out.println("child code execute");
}

Stub stub;
public Child(){
System.out.println("child constructor excute");
stub = new Stub("child constructor create object-");
}

public void sayHello(){
System.out.println("hello from child");
}
}
package com.jarreet.test;

public class TestParentChildExSequence {
public static void main(String[] args) {

Child child = new Child();
child.sayHello();
System.out.println("=====================================");
((Parent)child).sayHello();
}
}

開始分析:

  1. 首先會載入Parent,則Parent中的靜態程式碼塊和靜態成員變數會優先執行

  2. 載入Child,則Child中的靜態程式碼塊和靜態成員變數會優先執行

  3. 類載入完成之後,建立物件,先建立Parent物件,建立物件之前,先建立物件的資源

  4. 執行Parent構造器,完成Parent物件建立

  5. 建立Child物件之前,先建立Child的資源

  6. 執行Child構造器,完成Child物件建立

  7. 執行sayHello方法

    儘管進行強制型別轉換,但實際上物件本身還是記憶體中的子物件,所有hello都是來自於child

記憶體分析

  1. main()方法入棧,由於類Parent是類Child的父類,故先在方法區中載入Parnet的class物件,再載入Child的class物件(類的靜態屬性和靜態方法隨著類載入一同載入到記憶體中)

  2. 類載入完成之後,建立物件,先建立Parent物件,建立物件之前,先建立物件的資源,然後執行Parent構造器,完成Parent物件建立

  3. 接著建立Child物件,同樣先獲取物件的資源,然後再執行Child構造器,完成Child物件建立

  4. 執行sayHello()方法