1. 程式人生 > >java程式執行順序(main方法 靜態 非靜態 以及衍生出的部分定義)

java程式執行順序(main方法 靜態 非靜態 以及衍生出的部分定義)

Java程式執行時,第一件事情就是試圖訪問main方法,因為main相等於程式的入口,如果沒有main方法,程式將無法啟動,main方法更是佔一個獨立的執行緒。

下面是一段程式碼 幫助我們分析

class A {
    public A() {
        System.out.println("A的構造方法");
    }

    public static int j = print();

    public static int print() {
        System.out.println("A print");
        return 521;
    }
}

public class Test1 extends A {
    public Test1() {
        System.out.println("Test1的構造方法");
    }

    public static int k = print();

    public static int print() {
        System.out.println("Test print");
        return 522;
    }

    public static void main(String[] args) {
        System.out.println("main start");
        Test1 t1 = new Test1();
    }
}
執行結果:
A print
Test print
main start
A的構造方法
Test1的構造方法

分析:

因為靜態部分是依賴於類,而不是依賴於物件存在的,所以靜態部分的載入優先於物件存在。

  當找到main方法後,因為main方法雖然是一個特殊的靜態方法,但是還是靜態方法,此時JVM會載入main方法所在的類,試圖找到類中其他靜態部分,即首先會找main方法所在的類。

執行順序大致分類:

  1.靜態屬性,靜態方法宣告,靜態塊。

  2.動態屬性,普通方法宣告,構造塊。

  3.構造方法。

1.1 靜態:

  當載入一個類時,JVM會根據屬性的資料型別第一時間賦預設值(一舉生成的)。然後再進行靜態屬性初始化,併為靜態屬性分配記憶體空間,靜態方法的宣告,靜態塊的載入,沒有優先順序之分,按出現順序執行,靜態部分僅僅載入一次。至此為止,必要的類都已經載入完畢,物件就可以被建立了。

1.2 普通:

  當new一個物件時,此時會呼叫構造方法,但是在呼叫構造方法之前,(此刻1.1已經完成,除非被打斷而暫停)執行動態屬性定義並設定預設值(一舉生成的)。然後動態屬性初始化,分配記憶體,構造塊,普通方法宣告(只是載入,它不需要初始化,只有呼叫它時才分配記憶體,當方法執行完畢後記憶體立即釋放),沒有優先順序之分,按出現順序執行。最後進行構造方法中賦值。當再次建立一個物件,不再執行靜態部分,僅僅重複執行普通部分。

  注意:如果存在繼承關係,建立物件時,依然會首先進行動態屬性進行定義並設預設值,然後父類的構造器才會被呼叫,其他一切都是先父類再子類(因為子類的static初始化可能會依賴於父類成員能否被正確初始化),如果父類還有父類,依次類推,不管你是否打算產生一個該父類的物件,這都是自然發生的。

下面是一道阿里巴巴的面試題:非常經典,可以不斷的改變程式的順序,來找到執行順序機制。

  程式碼部分:

複製程式碼
public class Text {
    public static int k = 0;
    public static Text t1 = new Text("t1");
    public static Text t2 = new Text("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");

    {
        print("構造塊");
    }
    static {
        print("靜態塊");
    }

    public Text(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++i;
        ++n;
    }

    public static int print(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++n;
        return ++i;
    }

    public static void main(String args[]) {
        Text t = new Text("init");
    }
}
複製程式碼

   執行結果:

複製程式碼
1:j   i=0    n=0
2:構造塊   i=1    n=1
3:t1   i=2    n=2
4:j   i=3    n=3
5:構造塊   i=4    n=4
6:t2   i=5    n=5
7:i   i=6    n=6
8:靜態塊   i=7    n=99
9:j   i=8    n=100
10:構造塊   i=9    n=101
11:init   i=10    n=102

總結只要按照這個步驟,遇到這一類問題就可以解決了。     

          1-3:類載入過程,不涉及構造方法

          1-5: 例項化過程,涉及構造方法

  1.類中所有屬性的預設值(一舉而成)

  2. 父類靜態屬性初始化,靜態塊,靜態方法的宣告(按出現順序執行)

  3. 子類靜態屬性初始化,靜態塊,靜態方法的宣告 (按出現順序執行)

  4.  呼叫父類的構造方法,

      首先父類的非靜態成員初始化,構造塊,普通方法的宣告(按出現順序執行)

      然後父類構造方法

  5.  呼叫子類的構造方法,

      首先子類的非靜態成員初始化,構造塊,普通方法的宣告(按出現順序執行)

      然後子類構造方法

   注意:類載入過程中,可能呼叫了例項化過程(因為static可以修飾方法,屬性,程式碼塊,內部類),此時則會暫停類載入過程而先執行例項化過程(被打斷),執行結束再進行類載入過程,上面阿里那道面試題就是典型的暫停類載入。



相關推薦

java程式執行順序main方法 靜態 靜態 以及衍生部分定義

Java程式執行時,第一件事情就是試圖訪問main方法,因為main相等於程式的入口,如果沒有main方法,程式將無法啟動,main方法更是佔一個獨立的執行緒。 下面是一段程式碼 幫助我們分析class A { public A() { System

深入理解Java程式執行順序

下面將從一道阿里巴巴試題詳細分析Java程式執行順序。 阿里巴巴試題 public class Test { public static int k = 0; public static Test t1 = new Test("t1"); public static Test t

java程式執行順序理解

  public class StaticTest { public static int k = 0; public static StaticTest t1 = new StaticTest("t1"); public static StaticTest t2 =

深入瞭解類載入過程及Java程式執行順序

/** * @author chris * @date 2018/10/30 - 15:24 * 類載入執行順序: * 1.靜態屬性,靜態方法宣告,靜態塊。 * * 2.動態屬性,普通方法宣告,構造塊。 * * 3.構造方法。 * * 當new一個物件時,此時會呼叫構造方法,但是在呼叫構造方法之前,(除非被打

【轉】深入瞭解Java程式執行順序

Java中main方法,靜態,非靜態的執行順序詳解1 Java程式執行時,第一件事情就是試圖訪問main方法,因為main相等於程式的入口,如果沒有main方法,程式將無法啟動,main方法更是佔一個獨立的執行緒,找到main方法後,是不是就會執行mian方法塊裡的第一句話呢?答案是不一

Sublime Text 3 配置java程式執行環境可輸入

1、首先得配置好java環境2、Sublime Text 3--->Preference--->Browse Packages,開啟User資料夾,新建記事本,複製下面程式碼並儲存命名為java.sublime-build{ "cmd": ["javac"

Sublime Text3配置java程式執行環境引入不同jar包、輸入

相信很多童鞋都喜歡Sublime Text3這個編輯器,它的程式碼高亮等等都做的很好,也已經有很多人用它做c++程式的開發,但是關於java程式配置的資料卻幾乎沒有,網上我找到的都是最基本執行java的配置,花了兩天時間更加深入的研究了一下,以下給出能夠引入不同jar包以及

Java初始化順序靜態變量、靜態初始化塊、實例變量、實例初始化塊、構造方法

靜態初始化 都對 class block 註釋 執行順序 blog 中一 成員變量 1、執行順序 1.1、一個類中的初始化順序 (靜態變量、靜態初始化塊)=>(變量、初始化塊、構造器)。 1.2、兩個具有繼承關系類的初始化順序 父類的(靜態變量、

淺析java靜態方法靜態方法和構造方法執行順序問題

https://blog.csdn.net/qq_42401622/article/details/81190406 對於java中的靜態方法,非靜態方法和構造方法的理解: 靜態方法是隨著的java中虛擬機器的類的載入而載入,是跟隨繫結在一起的。 public class Main{ s

當一個類被載入後,它的靜態變數生命週期是什麼,是整個應用程式執行結束比如java web程式,從類載入到伺服器關閉還是該執行執行完畢還是別的什麼?

靜態變數在記憶體中只有一個,JAVA虛擬機器載入類的時候為其分配記憶體,位於方法區,被類的所有例項共享,其生命週期取決於類的生命週期。。。當類被解除安裝。。。靜態變數也被銷燬 取決於類載入器。如果換了一個類載入器,這個

JAVA靜態方法靜態方法,構造方法執行順序

一直不能理解java 中這三者的執行順序。@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

java中程式碼執行順序靜態程式碼塊、建構函式

1、方法、塊對應靜態和普通兩個級別,如果不產生例項,就只執行靜態部分,所有關聯類中的靜態部分總先於非靜態(例項化)部分執行。 2、靜態部分:靜態變數初始化--靜態程式碼塊--main方法。 3、非靜態部分(物件例項化過程):成員變數初始化--非靜態程式碼塊---建構函式 4、父類先於子類。靜態部分:父類靜態

Java靜態方法靜態方法實例方法的區別

外部類 允許 靜態成員 靜態 成員 訪問 靜態成員變量 ava 實例方法 靜態方法與實例方法的異同   1.在外部類 調用靜態方法時,有兩種方式:(1)類名.靜態方法()(2)類的對象.靜態方法() ;也就是說調用靜態方法時可以不用創建對象。      調用實例

為什麽javamain方法必須是靜態

博客 核心 log sync 簡單 chm 之前 excpetion 訪問 今天看類型信息時發現一個問題,不能再main方法中打印this關鍵字的信息,這時想起了之前的知識,不能再靜態方法中調用this。理由很簡單,this表示“這個對象”,也就是聲明一個類的對象,然而靜態

java中子類繼承父類程式執行順序問題

測試程式碼: package test; public class FatherTest { private String name; public FatherTest(){ System.out.println("--父類的無參建構函式--"); } public

java程式碼的MapReduce打包成jar 報錯: JAVA程式執行時出現:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsEx

以前的學習筆記,整理一下: java程式碼的MapReduce打包成jar 報錯: JAVA程式執行時出現:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at PrintWhat.main(Pri

Java執行java中的Sleep方法

點我跳過黑哥的卑鄙廣告行為,進入正文。 Java多執行緒系列更新中~   正式篇: Java多執行緒(一) 什麼是執行緒 Java多執行緒(二)關於多執行緒的CPU密集型和IO密集型這件事 Java多執行緒(三)如何建立執行緒 Java多執行緒(四)java中的Sleep方法  

當沒有繼承關係時,靜態塊、靜態方法靜態方法、構造方法、普通方法執行順序

<span style="font-size:18px;">package test; /** * 不含有繼承時,各種方法(靜態塊,靜態方法,非靜態程式碼塊,構造方法,普通方法)的執行順序 * */ public class uExt

Java:類檔案程式執行順序

只要按照這個步驟,遇到這一類問題就可以解決了。 1.類中所有屬性的預設值(一舉而成) 2. 父類靜態屬性初始化,靜態塊,靜態方法的宣告(按出現順序執行) 3. 子類靜態屬性初始化,靜態塊,靜態方法的宣告 (按出現順序執行) 4. 呼叫父類的構造方法, 首先父類的非靜態成員

java synchronized靜態同步方法靜態同步方法及同步塊

同步方法   同步方法所擁有的鎖就是該方法所屬的類的物件鎖,換句話說,也就是this物件,而且鎖的作用域也是整個方法,這可能導致其鎖的作用域可能太大,也有可能引起死鎖,同時因為可能包含了不需要進行同步的程式碼塊在內,也會降低程式的執行效率。 同步方法的鎖   同