1. 程式人生 > >簡單說說

簡單說說

<clinit>:在初始化時執行,從上到下的收集有初始值的靜態成員域或static塊的值,進行賦值,執行本類的<clinit>函式時,父類的<clinit>函式已經執行完畢,若本類不具有靜態成員域或static塊,則JVM不會為該類產生<clinit>函式。

<init>:其實就是建構函式,在生成class檔案時,編譯器會在建構函式中新增一些程式碼,在本類的建構函式中,會最優先呼叫父類的<init>函式,接著執行剩餘建構函式中剩餘的程式碼,我們來看看下面的程式碼:

class deal0 
{
  
}
class deal extends deal0
{
    int n;
    int m=2;
    deal()
    {
       n=1;
    }
}
public class Try {
    public static void main(String[] args) {
       deal x=new deal();
    } 
}

反編譯deal.class檔案:

  Last modified 2018-1-31; size 240 bytes
  MD5 checksum 8b1b2a8d7345905b383f50f5fd6d2a2a
  Compiled from "Try.java"
class deal extends deal0
  minor version: 0
  major version: 52
  flags: ACC_SUPER
Constant pool:
   #1 = Methodref          #5.#15         // deal0."<init>":()V
   #2 = Fieldref           #4.#16         // deal.m:I
   #3 = Fieldref           #4.#17         // deal.n:I
   #4 = Class              #18            // deal
   #5 = Class              #19            // deal0
   #6 = Utf8               n
   #7 = Utf8               I
   #8 = Utf8               m
   #9 = Utf8               <init>
  #10 = Utf8               ()V
  #11 = Utf8               Code
  #12 = Utf8               LineNumberTable
  #13 = Utf8               SourceFile
  #14 = Utf8               Try.java
  #15 = NameAndType        #9:#10         // "<init>":()V
  #16 = NameAndType        #8:#7          // m:I
  #17 = NameAndType        #6:#7          // n:I
  #18 = Utf8               deal
  #19 = Utf8               deal0
{
  int n;
    descriptor: I
    flags:

  int m;
    descriptor: I
    flags:

  deal();
    descriptor: ()V
    flags:
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0                           //將this指標壓入運算元棧
         1: invokespecial #1                  //Method deal0."<init>":()V,此處呼叫父類的建構函式,父類建構函式的執行結果寫入到this指標所指的記憶體處
         4: aload_0                           //將this指標壓入運算元棧
         5: iconst_2                          //將常量池中2壓入運算元棧
         6: putfield      #2                  // Field m:I,使記憶體中m的值為2,此時會用到運算元棧中的this指標,來找到例項物件在堆記憶體中的位置。
         9: aload_0                           //將this指標壓入運算元棧
        10: iconst_1                          //將常量池中的1壓入運算元棧,this指標作用同上
        11: putfield      #3                  // Field n:I,給記憶體中的n賦予1
        14: return
      LineNumberTable:
        line 10: 0
        line 8: 4
        line 11: 9
        line 12: 14
}
SourceFile: "Try.java"
建構函式的位元組碼解釋請看註釋,可以看到<init>先呼叫父類的<init>函式,接著初始化具有初始值的變數(實測後,初始化順序為程式碼中由上到下的出現順序),然後在執行我們自己寫的程式碼。