java-se - Java:请问这段代码的执行顺序是怎么样的,如果能够详细点更好,谢谢
PHPz
PHPz 2017-04-18 10:36:29
0
2
398
PHPz
PHPz

学习是最好的投资!

全部回覆(2)
小葫芦

類別變數(靜態變數)>靜態區塊>建構方法>普通成員變數>子類別除靜態外。 JAVA所有static修飾的都會在編譯時分配空間,而物件只會在使用時才分配即new的時候,子類別繼承父類別很明顯需要先給父類別分配,沒有父親哪來的兒子是吧

迷茫

題主可以透過編譯後的class檔反編譯來幫助理解初始化過程。

在命令列中的指令javap -l -c -p -v App,执行后就会得到反编译后的内容,下面结合题主给的源码简单分析一下:
下面展示和初始化有关的部分反编译内容
App的class檔案

private static com.real.test.App d;
  descriptor: Lcom/real/test/App;
  flags: ACC_PRIVATE, ACC_STATIC

private com.real.test.SubClass t;
  descriptor: Lcom/real/test/SubClass;
  flags: ACC_PRIVATE

static {};
  descriptor: ()V
  flags: ACC_STATIC
  Code:
    stack=2, locals=0, args_size=0
       0: new           #1                  // class com/real/test/App
       3: dup
       4: invokespecial #12                 // Method "<init>":()V  **调用App的构造函数**
       7: putstatic     #15                 // Field d:Lcom/real/test/App;
      10: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
      13: iconst_3   **得到数字常量3**
      14: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V   **打印数字常量3**
      17: return
    LineNumberTable:
      line 4: 0
      line 8: 10
      line 3: 17
    LocalVariableTable:
      Start  Length  Slot  Name   Signature

com.real.test.App();   **构造函数详细内容**
  descriptor: ()V
  flags:
  Code:
    stack=3, locals=1, args_size=1
       0: aload_0
       1: invokespecial #31                 // Method java/lang/Object."<init>":()V   **调用Object的构造函数**
       4: aload_0
       5: new           #32                 // class com/real/test/SubClass
       8: dup
       9: invokespecial #34                 // Method com/real/test/SubClass."<init>":()V   **调用SubClass的构造函数**
      12: putfield      #35                 // Field t:Lcom/real/test/SubClass;
      15: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
      18: iconst_4   **得到数字常量4**
      19: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V   **打印数字常量4**
      22: return
    LineNumberTable:
      line 11: 0
      line 5: 4
      line 12: 15
      line 13: 22
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      23     0  this   Lcom/real/test/App;

public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=2, locals=1, args_size=1
       0: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #40                 // String Hello  **得到字符串Hello**
       5: invokevirtual #42                 // Method java/io/PrintStream.println:(Ljava/lang/String   **打印字符串**
       8: return
    LineNumberTable:
      line 16: 0
      line 17: 8
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       9     0  args   [Ljava/lang/String;

SubClass的class檔案

static {};  **静态块**
  descriptor: ()V
  flags: ACC_STATIC
  Code:
    stack=2, locals=0, args_size=0
       0: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: iconst_1   **得到数字常量1**
       4: invokevirtual #14                 // Method java/io/PrintStream.println:(I)V   **打印数字常量1**
       7: return
    LineNumberTable:
      line 28: 0
      line 26: 7
    LocalVariableTable:
      Start  Length  Slot  Name   Signature

public com.real.test.SubClass();  **构造函数**
  descriptor: ()V
  flags: ACC_PUBLIC
  Code:
    stack=2, locals=1, args_size=1
       0: aload_0
       1: invokespecial #23                 // Method com/real/test/SuperClass."<init>":()V   **调用SuperClass的构造函数**
       4: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
       7: iconst_2   **得到数字常量2**
       8: invokevirtual #14                 // Method java/io/PrintStream.println:(I)V   **打印数字常量2**
      11: return
    LineNumberTable:
      line 31: 0
      line 32: 4
      line 33: 11
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      12     0  this   Lcom/real/test/SubClass;

SuperClass的class檔案

 com.real.test.SuperClass();
   descriptor: ()V
   flags:
   Code:
     stack=2, locals=1, args_size=1
        0: aload_0
        1: invokespecial #8                  // Method java/lang/Object."<init>":()V   **Object的构造函数**
        4: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
        7: ldc           #16                 // String 构造SuperClass   **得到字符串构造SuperClass**
        9: invokevirtual #18                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V   **打印字符串**
       12: return
     LineNumberTable:
       line 21: 0
       line 22: 4
       line 23: 12
     LocalVariableTable:
       Start  Length  Slot  Name   Signature
           0      13     0  this   Lcom/real/test/SuperClass;

大致解釋一下內容(如果題主對JVM指令集有興趣看看JVM規範,裡面有很詳細的解釋)。
上面反編譯內容中星號部分是我加上的註解。依照程式碼的執行順序:
1.JVM載入App類,App中的靜態變數在這時會初始化,對應App中呼叫App的建構函數的字節碼
2.跳到App的建構函數,先初始化父類別Object,對應App中呼叫Object的建構子
3.初始化實例變數JVM指令集感兴趣可以看看JVM规范,里面有很详细的解释)。
上面反编译内容中星号部分是我加上的注解。按照代码的执行顺序:
1.JVM加载App类,App中的静态变量在这时会初始化,对应App中调用App的构造函数的字节码
2.跳到App的构造函数,先初始化父类Object,对应App中调用Object的构造函数
3.初始化实例变量SubClass,对应App中调用SubClass的构造函数
4.此时要先加载SubClass类,同时初始化静态变量并执行静态块,对应SubClass中静态块
5.这时执行SubClass中的代码打印出“1”
6.SubClass加载完成后执行构造函数,对应SubClass中构造函数
7.SubClass构造函数最开始是执行SuperClass的构造函数,对应SubClass中调用SuperClass的构造函数
8.执行SuperClass中构造函数中的代码打印出“得到字符串构造SuperClass”
9.SuperClass构造完成return到7中的代码位置,继续执行SubClass剩余的代码
10.执行SubClass中构造函数代码打印出“2”
11.执行完SubClass构造函数return到3中的代码位置,继续执行App剩余的代码
12.执行App中构造函数代码打印出“4”
13.执行完App的构造函数return到1中代码位置,继续初始化的静态变量
14.执行静态块中的方法,答应出“3”
15.进入到main,對應App中呼叫SubClass的建構子
4.此時要先載入

類,同時初始化靜態變數並執行靜態區塊,對應SubClass中靜態區塊
5.這時執行

中的程式碼列印出「1」
6.

載入完成後執行建構函數,對應SubClass中建構子
7.

建構子最開始是執行

的建構函數,對應SubClass中呼叫SuperClass的建構子
8.執行🎜中建構函數中的程式碼印出「得到字串構造SuperClass」
9.🎜構造完成return到7中的程式碼位置,繼續執行🎜剩餘的程式碼
10.執行🎜中構造函式碼印出「2」
11.執行完🎜建構子return到3中的程式碼位置,繼續執行App剩餘的程式碼
12.執行App中建構函式碼印出「4」
13.執行完App的建構子return到1中程式碼位置,繼續初始化的靜態變數
14.執行靜態區塊中的方法,答應出「3」
15.進入到main入口方法,列印出「Hello」🎜 🎜上面的過程就是大致的執行順序。 🎜 🎜回答的內容可能會有點混亂,題主看不懂的地方可以問我。 🎜
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板