Java Class文件學習

編程語言 Java Java虛擬機 Line 科技優家 2017-06-20

數據類型:

Java Class文件學習Java Class文件學習

class 文件結構

minor version:副版本

major version:主版本號

文件的版本號 major_version.minor_version

flags:訪問標誌

  1. ACC_PUBLICH 聲明為publich
  2. ACC_FINAL 聲明為final
  3. ACC_SUPER 當用到invokespecial指令時,需要對父類方法做特殊處理
  4. ACC_INTERFACE 該class文件定義的是接口而不是類
  5. ACC_ABSTRACT 聲明為abstract
  6. ACC_SYNTHETIC 聲明為synthetic
  7. ACC_ANNOTATION 標識註解類型
  8. ACC_ENUM 標識枚舉類型

constant pool 常量池

方法調用和返回指令

  1. invokevirtual 指令用於調用對象的實例方法,根據對象的實際類型進行分派
  2. invokeinterface 指令用於調用接口方法,它會在運行時搜索由特定對象實現的這個接口方法,並找出適合的方法進行調用
  3. invokespecial 指令用於調用一些需要特殊的實例方法,包括實例的初始化,私有方法和父類方法
  4. invokestatic 指令用於調用命名類中的靜態方法
  5. invokedynamic 指令用於調用可以綁定invokedynamic指令的調用點對象作為目標方法。

aaload_<n>:從局部變量表中加載索引值為n的引用

aconst_null:將一個null值壓入到操作數棧頂

putfield:為制定類的字段賦值

通過執行javac xxx.java javap -verbose xxx.class 查看class文件

public class AconstNullDemo {
    Integer i=null;

    void test{
        i=1;
        if(i.equals(Integer.valueOf(1))){
 System.out.println("eq");
        }
    }
}


public class common.jvm.AconstNullDemo
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref #9.#20         // java/lang/Object."<init>":V
   #2 = Fieldref #8.#21         // common/jvm/AconstNullDemo.i:Ljava/lang/Integer;
   #3 = Methodref #22.#23        // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   #4 = Methodref #22.#24        // java/lang/Integer.equals:(Ljava/lang/Object;)Z
   #5 = Fieldref #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
   #6 = String #27 // eq
   #7 = Methodref #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #8 = Class #30 // common/jvm/AconstNullDemo
   #9 = Class #31 // java/lang/Object
  #10 = Utf8 i
  #11 = Utf8 Ljava/lang/Integer;
  #12 = Utf8 <init>
  #13 = Utf8 V
  #14 = Utf8 Code
  #15 = Utf8 LineNumberTable
  #16 = Utf8 test
  #17 = Utf8 StackMapTable
  #18 = Utf8 SourceFile
  #19 = Utf8 AconstNullDemo.java
  #20 = NameAndType        #12:#13        // "<init>":V
  #21 = NameAndType        #10:#11        // i:Ljava/lang/Integer;
  #22 = Class #32 // java/lang/Integer
  #23 = NameAndType        #33:#34        // valueOf:(I)Ljava/lang/Integer;
  #24 = NameAndType        #35:#36        // equals:(Ljava/lang/Object;)Z
  #25 = Class #37 // java/lang/System
  #26 = NameAndType        #38:#39        // out:Ljava/io/PrintStream;
  #27 = Utf8 eq
  #28 = Class #40 // java/io/PrintStream
  #29 = NameAndType        #41:#42        // println:(Ljava/lang/String;)V
  #30 = Utf8 common/jvm/AconstNullDemo
  #31 = Utf8 java/lang/Object
  #32 = Utf8 java/lang/Integer
  #33 = Utf8 valueOf
  #34 = Utf8 (I)Ljava/lang/Integer;
  #35 = Utf8 equals
  #36 = Utf8 (Ljava/lang/Object;)Z
  #37 = Utf8 java/lang/System
  #38 = Utf8 out
  #39 = Utf8 Ljava/io/PrintStream;
  #40 = Utf8 java/io/PrintStream
  #41 = Utf8 println
  #42 = Utf8 (Ljava/lang/String;)V
{
  java.lang.Integer i;
    descriptor: Ljava/lang/Integer;
    flags:

  public common.jvm.AconstNullDemo;
    descriptor: V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1 // Method java/lang/Object."<init>":V
         4: aload_0
         //將null壓入棧頂
         5: aconst_null
         //將null賦值給屬性i
         6: putfield      #2 // Field i:Ljava/lang/Integer;
         9: return
      LineNumberTable:
        line 6: 0
        line 7: 4

  void test;
    descriptor: V
    flags:
    Code:
      stack=2, locals=1, args_size=1
        //加載this到操作棧
         0: aload_0  
         //加載常量1到操作棧
         1: iconst_1
         //調用靜態方法
         2: invokestatic  #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         //將計算結果賦值給屬性,為什麼putfield的索引不是連續的?這是因為invokestatic操作和操作數長度為3個slot
         5: putfield      #2 // Field i:Ljava/lang/Integer;
         //加載this到操作棧
         8: aload_0
         //將屬性壓入棧頂
         9: getfield      #2 // Field i:Ljava/lang/Integer;
        //加載常量1到操作棧頂
        12: iconst_1
        //調用靜態方法Integer.valueOf
        13: invokestatic  #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        //調用虛方法equals
        16: invokevirtual #4 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z
        //如果ifeq的結果為0則挑戰到30行
        19: ifeq 30
        22: getstatic     #5 // Field java/lang/System.out:Ljava/io/PrintStream;
        25: ldc #6 // String eq
        27: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        30: return
      LineNumberTable:
        line 10: 0
        line 11: 8
        line 12: 22
        line 14: 30
      StackMapTable: number_of_entries = 1
        frame_type = 30 /* same */
}

相關推薦

推薦中...