深入理解字节码文件

public class Bytecode {
    public  static void main(String arg[]){
        Bytecode bc= new Bytecode();
        System.out.println(bc.fib(4));
    }
    public int fib(int N) {
        if (N <= 1) {
            return N;
        }
        return fib(N-1) + fib(N-2);
    }
}

用一个递归程序深入理解字节码文件

public class Java_jvm.Bytecode
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#19         // java/lang/Object."<init>":()V
   #2 = Class              #20            // Java_jvm/Bytecode
   #3 = Methodref          #2.#19         // Java_jvm/Bytecode."<init>":()V
   #4 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;
   #5 = Methodref          #2.#23         // Java_jvm/Bytecode.fib:(I)I
   #6 = Methodref          #24.#25        // java/io/PrintStream.println:(I)V
   #7 = Class              #26            // java/lang/Object
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               main
  #13 = Utf8               ([Ljava/lang/String;)V
  #14 = Utf8               fib
  #15 = Utf8               (I)I
  #16 = Utf8               StackMapTable
  #17 = Utf8               SourceFile
  #18 = Utf8               Bytecode.java
  #19 = NameAndType        #8:#9          // "<init>":()V
  #20 = Utf8               Java_jvm/Bytecode
  #21 = Class              #27            // java/lang/System
  #22 = NameAndType        #28:#29        // out:Ljava/io/PrintStream;
  #23 = NameAndType        #14:#15        // fib:(I)I
  #24 = Class              #30            // java/io/PrintStream
  #25 = NameAndType        #31:#32        // println:(I)V
  #26 = Utf8               java/lang/Object
  #27 = Utf8               java/lang/System
  #28 = Utf8               out
  #29 = Utf8               Ljava/io/PrintStream;
  #30 = Utf8               java/io/PrintStream
  #31 = Utf8               println
  #32 = Utf8               (I)V
{
  public Java_jvm.Bytecode();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=2, args_size=1
         0: new           #2                  // class Java_jvm/Bytecode
         3: dup                              
           然后因为invokespecial会消耗掉操作数栈顶的引用作为传给构造器的“this”参数,所以如果我们希望在invokespecial调用后在操作数栈顶还维持有一个指向新建对象的引用,   就得在invokespecial之前先“复制”一份引用
4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
        11: aload_1
        12: iconst_4
        13: invokevirtual #5                  // Method fib:(I)I
        16: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V
        19: return
      LineNumberTable:
        line 5: 0
        line 6: 8
        line 7: 19

  public int fib(int);
    descriptor: (I)I
    flags: ACC_PUBLIC
    Code:
      stack=4, locals=2, args_size=2
         0: iload_1
         1: iconst_1
         2: if_icmpgt     7
         5: iload_1
         6: ireturn
         7: aload_0
         8: iload_1
         9: iconst_1
        10: isub
        11: invokevirtual #5                  // Method fib:(I)I
        14: aload_0
        15: iload_1
        16: iconst_2
        17: isub
        18: invokevirtual #5                  // Method fib:(I)I
        21: iadd
        22: ireturn
      LineNumberTable:
        line 9: 0
        line 10: 5
        line 12: 7
      StackMapTable: number_of_entries = 1
        frame_type = 7 /* same */
}
原文地址:https://www.cnblogs.com/peterleee/p/12878401.html