Classファイル解析例

14570 ワード

JAvaファイルをclassバイトコードファイルにコンパイルした場合、例は以下の通りです.
Classfile /target/classes/com/jvm/bookdemo/z6/ClassCompileTest.class
  Last modified May 17, 2019; size 1969 bytes
  MD5 checksum 10ce34e6f69adca226d421a8ae082da0
  Compiled from "ClassCompileTest.java"
public class com.jvm.bookdemo.z6.ClassCompileTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Methodref          #25.#66       // java/lang/Object."":()V
    #2 = Class              #67           // java/lang/Long
    #3 = Long               9223372036854775807l
    #5 = Methodref          #2.#68        // java/lang/Long.valueOf:(J)Ljava/lang/Long;
    #6 = Fieldref           #69.#70       // java/lang/System.out:Ljava/io/PrintStream;
    #7 = Methodref          #71.#72       // java/io/PrintStream.println:(Ljava/lang/Object;)V
    #8 = Methodref          #71.#73       // java/io/PrintStream.println:(I)V
    #9 = Class              #74           // java/util/ArrayList
   #10 = Methodref          #9.#66        // java/util/ArrayList."":()V
   #11 = Class              #75           // com/jvm/bookdemo/z6/ClassCompileTest
   #12 = Methodref          #11.#66       // com/jvm/bookdemo/z6/ClassCompileTest."":()V
   #13 = InterfaceMethodref #76.#77       // java/util/List.add:(Ljava/lang/Object;)Z
   #14 = Class              #78           // java/lang/StringBuffer
   #15 = Methodref          #14.#79       // java/lang/StringBuffer."":(Ljava/lang/String;)V
   #16 = Methodref          #14.#80       // java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
   #17 = Methodref          #14.#81       // java/lang/StringBuffer.toString:()Ljava/lang/String;
   #18 = String             #82           // 4E
   #19 = Methodref          #83.#84       // java/lang/Integer.parseInt:(Ljava/lang/String;I)I
   #20 = Methodref          #83.#85       // java/lang/Integer.toHexString:(I)Ljava/lang/String;
   #21 = Methodref          #71.#86       // java/io/PrintStream.println:(Ljava/lang/String;)V
   #22 = String             #87           // 222
   #23 = Fieldref           #11.#88       // com/jvm/bookdemo/z6/ClassCompileTest.CONSTANT_PARAM:Ljava/lang/String;
   #24 = Fieldref           #11.#89       // com/jvm/bookdemo/z6/ClassCompileTest.INT_PARAM:I
   #25 = Class              #90           // java/lang/Object
   #26 = Utf8               FINAL_CONSTANT_PARAM
   #27 = Utf8               Ljava/lang/String;
   #28 = Utf8               ConstantValue
   #29 = String             #91           // 111
   #30 = Utf8               CONSTANT_PARAM
   #31 = Utf8               INT_PARAM
   #32 = Utf8               I
   #33 = Utf8               
   #34 = Utf8               ()V
   #35 = Utf8               Code
   #36 = Utf8               LineNumberTable
   #37 = Utf8               LocalVariableTable
   #38 = Utf8               this
   #39 = Utf8               Lcom/jvm/bookdemo/z6/ClassCompileTest;
   #40 = Utf8               appendStr
   #41 = Utf8               (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
   #42 = Utf8               paraStr
   #43 = Utf8               prefix
   #44 = Utf8               g
   #45 = Utf8               Ljava/lang/Long;
   #46 = Utf8               a
   #47 = Utf8               b
   #48 = Utf8               c
   #49 = Utf8               d
   #50 = Utf8               e
   #51 = Utf8               f
   #52 = Utf8               list
   #53 = Utf8               Ljava/util/List;
   #54 = Utf8               ct
   #55 = Utf8               sb
   #56 = Utf8               Ljava/lang/StringBuffer;
   #57 = Utf8               LocalVariableTypeTable
   #58 = Utf8               Ljava/util/List;
   #59 = Utf8               main
   #60 = Utf8               ([Ljava/lang/String;)V
   #61 = Utf8               args
   #62 = Utf8               [Ljava/lang/String;
   #63 = Utf8               
   #64 = Utf8               SourceFile
   #65 = Utf8               ClassCompileTest.java
   #66 = NameAndType        #33:#34       // "":()V
   #67 = Utf8               java/lang/Long
   #68 = NameAndType        #92:#93       // valueOf:(J)Ljava/lang/Long;
   #69 = Class              #94           // java/lang/System
   #70 = NameAndType        #95:#96       // out:Ljava/io/PrintStream;
   #71 = Class              #97           // java/io/PrintStream
   #72 = NameAndType        #98:#99       // println:(Ljava/lang/Object;)V
   #73 = NameAndType        #98:#100      // println:(I)V
   #74 = Utf8               java/util/ArrayList
   #75 = Utf8               com/jvm/bookdemo/z6/ClassCompileTest
   #76 = Class              #101          // java/util/List
   #77 = NameAndType        #102:#103     // add:(Ljava/lang/Object;)Z
   #78 = Utf8               java/lang/StringBuffer
   #79 = NameAndType        #33:#104      // "":(Ljava/lang/String;)V
   #80 = NameAndType        #105:#106     // append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
   #81 = NameAndType        #107:#108     // toString:()Ljava/lang/String;
   #82 = Utf8               4E
   #83 = Class              #109          // java/lang/Integer
   #84 = NameAndType        #110:#111     // parseInt:(Ljava/lang/String;I)I
   #85 = NameAndType        #112:#113     // toHexString:(I)Ljava/lang/String;
   #86 = NameAndType        #98:#104      // println:(Ljava/lang/String;)V
   #87 = Utf8               222
   #88 = NameAndType        #30:#27       // CONSTANT_PARAM:Ljava/lang/String;
   #89 = NameAndType        #31:#32       // INT_PARAM:I
   #90 = Utf8               java/lang/Object
   #91 = Utf8               111
   #92 = Utf8               valueOf
   #93 = Utf8               (J)Ljava/lang/Long;
   #94 = Utf8               java/lang/System
   #95 = Utf8               out
   #96 = Utf8               Ljava/io/PrintStream;
   #97 = Utf8               java/io/PrintStream
   #98 = Utf8               println
   #99 = Utf8               (Ljava/lang/Object;)V
  #100 = Utf8               (I)V
  #101 = Utf8               java/util/List
  #102 = Utf8               add
  #103 = Utf8               (Ljava/lang/Object;)Z
  #104 = Utf8               (Ljava/lang/String;)V
  #105 = Utf8               append
  #106 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuffer;
  #107 = Utf8               toString
  #108 = Utf8               ()Ljava/lang/String;
  #109 = Utf8               java/lang/Integer
  #110 = Utf8               parseInt
  #111 = Utf8               (Ljava/lang/String;I)I
  #112 = Utf8               toHexString
  #113 = Utf8               (I)Ljava/lang/String;
{
  public static final java.lang.String FINAL_CONSTANT_PARAM;
    descriptor: Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: String 111

  public static java.lang.String CONSTANT_PARAM;
    descriptor: Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_STATIC

  public static int INT_PARAM;
    descriptor: I
    flags: ACC_PUBLIC, ACC_STATIC

  public com.jvm.bookdemo.z6.ClassCompileTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: return
      LineNumberTable:
        line 13: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/jvm/bookdemo/z6/ClassCompileTest;

  public java.lang.String appendStr(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=13, args_size=3
         0: ldc2_w        #3                  // long 9223372036854775807l  //ldc2_w         long               
         3: invokestatic  #5                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
         6: astore_3
         7: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        10: aload_3
        11: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
        14: iconst_1
        15: istore        4
        17: bipush        12
        19: istore        5
        21: iconst_3
        22: istore        6
        24: iconst_4
        25: istore        7
        27: bipush        6
        29: istore        8
        31: iload         4
        33: iload         5
        35: iconst_3
        36: imul
        37: iadd
        38: iload         6
        40: iadd
        41: iload         7
        43: iadd
        44: iload         8
        46: iadd
        47: istore        9
        49: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        52: iload         9
        54: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V
        57: new           #9                  // class java/util/ArrayList
        60: dup
        61: invokespecial #10                 // Method java/util/ArrayList."":()V
        64: astore        10
        66: new           #11                 // class com/jvm/bookdemo/z6/ClassCompileTest
        69: dup
        70: invokespecial #12                 // Method "":()V
        73: astore        11
        75: aload         10
        77: aload         11
        79: invokeinterface #13,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
        84: pop
        85: new           #14                 // class java/lang/StringBuffer
        88: dup
        89: aload_1
        90: invokespecial #15                 // Method java/lang/StringBuffer."":(Ljava/lang/String;)V
        93: astore        12
        95: aload         12
        97: aload_2
        98: invokevirtual #16                 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
       101: pop
       102: aload         12
       104: invokevirtual #17                 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
       107: areturn
      LineNumberTable:
        line 20: 0
        line 21: 7
        line 23: 14
        line 24: 17
        line 25: 21
        line 26: 24
        line 27: 27
        line 28: 31
        line 29: 49
        line 32: 57
        line 33: 66
        line 34: 75
        line 35: 85
        line 36: 95
        line 37: 102
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0     108     0  this   Lcom/jvm/bookdemo/z6/ClassCompileTest;
            0     108     1 paraStr   Ljava/lang/String;
            0     108     2 prefix   Ljava/lang/String;
            7     101     3     g   Ljava/lang/Long;
           17      91     4     a   I
           21      87     5     b   I
           24      84     6     c   I
           27      81     7     d   I
           31      77     8     e   I
           49      59     9     f   I
           66      42    10  list   Ljava/util/List;
           75      33    11    ct   Lcom/jvm/bookdemo/z6/ClassCompileTest;
           95      13    12    sb   Ljava/lang/StringBuffer;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
           66      42    10  list   Ljava/util/List;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=1, args_size=1
         0: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #18                 // String 4E
         5: bipush        16
         7: invokestatic  #19                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;I)I
        10: invokevirtual #8                  // Method java/io/PrintStream.println:(I)V
        13: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        16: bipush        33
        18: invokestatic  #20                 // Method java/lang/Integer.toHexString:(I)Ljava/lang/String;
        21: invokevirtual #21                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        24: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        27: sipush        16385
        30: invokestatic  #20                 // Method java/lang/Integer.toHexString:(I)Ljava/lang/String;
        33: invokevirtual #21                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        36: return
      LineNumberTable:
        line 43: 0
        line 44: 13
        line 45: 24
        line 46: 36
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      37     0  args   [Ljava/lang/String;

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: ldc           #22                 // String 222
         2: putstatic     #23                 // Field CONSTANT_PARAM:Ljava/lang/String;
         5: bipush        96
         7: putstatic     #24                 // Field INT_PARAM:I
        10: return
      LineNumberTable:
        line 15: 0
        line 16: 5
}
SourceFile: "ClassCompileTest.java"

  public java.lang.String appendStr(java.lang.String, java.lang.String);     descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;     flags: ACC_PUBLIC//メソッドテーブル構造の最初の2バイト、ACC_PUBLIC代表メソッドはpublic Code://Codeはメソッドテーブル構造内の属性であり、attribute_に対応するinfoの最初の2バイトattribute_name_index,定数プール内のcodeを指すインデックス(例では#35)stack=3、locals=13、args_size=3//stack=3はスタックフレーム深さ3(max_stack)、locals=13を表す(ローカル変数テーブルを表すために必要な記憶領域はSloatsが13個)、args_size=3はメソッドを表すパラメータが3個で、それぞれthis、Stringタイプ、Stringタイプ0:ldc 2_w 3//long 922337203685475807 l//ldc 2_w命令は、longタイプ定数値を定数プールからスタックトップにプッシュすることを意味する       3: invokestatic  #5                 //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;//静的メソッドを呼び出す、ここではLongを呼び出す.valueOfメソッド6:astore_3//4番目の参照タイプ(参照タイプLocalVariableTableの下からSlot列3の名前が見つかり、対応するnameはg)ローカル変数がスタックトップにプッシュされます.つまり、上で計算した結果、スタックトップ7:getstatic#6//Field java/lang/System.out:Ljava/io/printStream;//指定したクラスの静的ドメインを取得し、スタックにプッシュします.トップ.ここの後ろ10:aload_3//4番目の参照タイプ(つまりLocalVariableTableの下のnameが「g」のパラメータ)をスタックトップ11:invokevirtual#7//Method java/io/printStream.println:(Ljava/lang/Object;)V//インスタンスメソッドを呼び出し、java/io/printStreamを呼び出す.println
       14: iconst_1//intタイプ値1をスタックトップにプッシュ