javap 例子

public static void test(){
        String a = "x"+"y"+"1";
        String b = "xy1";
        System.out.println(a == b);
    }


public class test.Test8
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             // test/Test8
   #2 = Utf8               test/Test8
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Ltest/Test8;
  #14 = Utf8               test
  #15 = String             #16            // xy1
  #16 = Utf8               xy1
  #17 = Fieldref           #18.#20        // java/lang/System.out:Ljava/io/PrintStream;
  #18 = Class              #19            // java/lang/System
  #19 = Utf8               java/lang/System
  #20 = NameAndType        #21:#22        // out:Ljava/io/PrintStream;
  #21 = Utf8               out
  #22 = Utf8               Ljava/io/PrintStream;
  #23 = Methodref          #24.#26        // java/io/PrintStream.println:(Z)V
  #24 = Class              #25            // java/io/PrintStream
  #25 = Utf8               java/io/PrintStream
  #26 = NameAndType        #27:#28        // println:(Z)V
  #27 = Utf8               println
  #28 = Utf8               (Z)V
  #29 = Utf8               a
  #30 = Utf8               Ljava/lang/String;
  #31 = Utf8               b
  #32 = Utf8               StackMapTable
  #33 = Class              #34            // java/lang/String
  #34 = Utf8               java/lang/String
  #35 = Utf8               SourceFile
  #36 = Utf8               Test8.java
{
  public test.Test8();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:   // 代码行数  对应的字节码序号
        line 3: 0        // 源文件第三行代码对应第0个字节码序号
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Ltest/Test8;

  public static void test();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=2, args_size=0  // stack=3代表本地栈的slot个数为3,俩个String需要load,System的out也会占用一个,当发生对比生成boolean的时候,会将俩个String的引用从栈顶pop出来,所以最多是3个slot。Locals为2,因为只有俩个String,如果是非静态方法,则本地变量会自动增加this。
         0: ldc           #15                 // String xy1
         2: astore_0
         3: ldc           #15                 // String xy1
         5: astore_1
         6: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
         9: aload_0
        10: aload_1
        11: if_acmpne     18
        14: iconst_1
        15: goto          19
        18: iconst_0
        19: invokevirtual #23                 // Method java/io/PrintStream.println:(Z)V
        22: return
      LineNumberTable:
        line 5: 0
        line 6: 3
        line 7: 6
        line 8: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            3      20     0     a   Ljava/lang/String; // 第一个本地变量的作用区域从第三个字节的位置开始,作用区域范围为20个字节,所在slot的位置是第0个位置,名称为a,类型为java.lang.String
            6      17     1     b   Ljava/lang/String;
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 18
          locals = [ class java/lang/String, class java/lang/String ]
          stack = [ class java/io/PrintStream ]
        frame_type = 255 /* full_frame */
          offset_delta = 0
          locals = [ class java/lang/String, class java/lang/String ]
          stack = [ class java/io/PrintStream, int ]
}

Stack代表栈顶的单位大小(每个大小为1个slot,每个slot是4个字节的宽度),这里的栈的宽度为1,代表有一个this将会被使用。

Locals代表本地变量的slot个数,代表本地变量在这个方法生命周期内,局部变量最多的时候,需要多大的宽度来存放数据(double、long会占用俩个slot)。

args_size代表的是入口参数个数。


invokespecial #1;//Method java/lang/Object."<init>":()V

当发生构造方法调用、父类的构造方法调用、非静态的private方法调用时会使用该指令,这里需要从常量池中获取一个方法,这个地方会占用2个字节的宽度。


jvm指令官方文档:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-7.html

以上内容摘自《Java特种兵》 作者:谢宇


2.摘自《Java特种兵》 作者:谢宇

public static void test(){
        int a=1,b=1,c=1,d=1;
        
        a++;
        ++b;
        c = c++;
        d = ++d; // The assignment to variable d has no effect
        // System.out.println(a +b + c + d); // 2,2,1,2
    }

public class test.Test8
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             // test/Test8
   #2 = Utf8               test/Test8
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Ltest/Test8;
  #14 = Utf8               test
  #15 = Utf8               a
  #16 = Utf8               I
  #17 = Utf8               b
  #18 = Utf8               c
  #19 = Utf8               d
  #20 = Utf8               SourceFile
  #21 = Utf8               Test8.java
{
  public test.Test8();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Ltest/Test8;

  public static void test();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=4, args_size=0
         0: iconst_1
         1: istore_0
         2: iconst_1
         3: istore_1
         4: iconst_1
         5: istore_2
         6: iconst_1
         7: istore_3
         8: iinc          0, 1
        11: iinc          1, 1
        14: iload_2
        15: iinc          2, 1
        18: istore_2
        19: iinc          3, 1
        22: iload_3
        23: istore_3
        24: return
      LineNumberTable:
        line 5: 0   // 对应 int a=1,b=1,c=1,d=1;
        line 7: 8   // 对应 a++;
        line 8: 11  // 对应 ++b;
        line 9: 14  //      c = c++;
        line 10: 19 //      d = ++d;
        line 12: 24
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            2      23     0     a   I
            4      21     1     b   I
            6      19     2     c   I
            8      17     3     d   I
}

3.

public static void test(){
        int i = 0;
        int x = (i++) + (++i) + (i++);
    }


public static void test();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=0
         0: iconst_0
         1: istore_0
         2: iload_0
         3: iinc          0, 1
         6: iinc          0, 1
         9: iload_0
        10: iadd
        11: iload_0
        12: iinc          0, 1
        15: iadd
        16: istore_1
        17: return
      LineNumberTable:
        line 5: 0
        line 6: 2
        line 7: 17
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            2      16     0     i   I
           17       1     1     x   I



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值