package cn.itcast.jvm.t3.bytecode;/**
* 演示 字节码指令 和 操作数栈、常量池的关系
*/
public class Demo3_1 {public static void main(String[] args) {int a = 10;int b = Short.MAX_VALUE + 1;int c = a + b;System.out.println(c);}
}
[root@localhost ~]# javap -v Demo3_1.class
Classfile /root/Demo3_1.classLast modified Jul 7, 2019; size 665 bytesMD5 checksum a2c29a22421e218d4924d31e6990cfc5Compiled from "Demo3_1.java"
public class cn.itcast.jvm.t3.bytecode.Demo3_1minor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref #7.#26 // java/lang/Object."":()V#2 = Class #27 // java/lang/Short#3 = Integer 32768#4 = Fieldref #28.#29 //java/lang/System.out:Ljava/io/PrintStream;#5 = Methodref #30.#31 // java/io/PrintStream.println:(I)V#6 = Class #32 // cn/itcast/jvm/t3/bytecode/Demo3_1#7 = Class #33 // java/lang/Object#8 = Utf8 #9 = Utf8 ()V#10 = Utf8 Code#11 = Utf8 LineNumberTable#12 = Utf8 LocalVariableTable#13 = Utf8 this#14 = Utf8 Lcn/itcast/jvm/t3/bytecode/Demo3_1;#15 = Utf8 main#16 = Utf8 ([Ljava/lang/String;)V#17 = Utf8 args#18 = Utf8 [Ljava/lang/String;#19 = Utf8 a#20 = Utf8 I#21 = Utf8 b#22 = Utf8 c#23 = Utf8 MethodParameters#24 = Utf8 SourceFile#25 = Utf8 Demo3_1.java#26 = NameAndType #8:#9 // "":()V#27 = Utf8 java/lang/Short#28 = Class #34 // java/lang/System#29 = NameAndType #35:#36 // out:Ljava/io/PrintStream;#30 = Class #37 // java/io/PrintStream#31 = NameAndType #38:#39 // println:(I)V#32 = Utf8 cn/itcast/jvm/t3/bytecode/Demo3_1#33 = Utf8 java/lang/Object#34 = Utf8 java/lang/System#35 = Utf8 out#36 = Utf8 Ljava/io/PrintStream;#37 = Utf8 java/io/PrintStream#38 = Utf8 println#39 = Utf8 (I)V
{public cn.itcast.jvm.t3.bytecode.Demo3_1();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."":()V4: returnLineNumberTable:line 6: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcn/itcast/jvm/t3/bytecode/Demo3_1;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=4, args_size=10: bipush 102: istore_13: ldc #3 // int 327685: istore_26: iload_17: iload_28: iadd9: istore_310: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;13: iload_314: invokevirtual #5 // Method java/io/PrintStream.println:(I)V17: returnLineNumberTable:line 8: 0line 9: 3line 10: 6line 11: 10line 12: 17LocalVariableTable:Start Length Slot Name Signature0 18 0 args [Ljava/lang/String;3 15 1 a I6 12 2 b I10 8 3 c IMethodParameters:Name Flagsargs
}
(stack=2,locals=4)
将一个 byte 压入操作数栈(其长度会补齐 4 个字节),类似的指令还有:
将操作数栈顶数据弹出,存入局部变量表的 slot 1
从常量池加载 #3 数据到操作数栈
注意:Short.MAX_VALUE 是 32767,所以 32768 = Short.MAX_VALUE + 1 实际是在编译期间计算 好的
找到常量池 #5 项
定位到方法区 java/io/PrintStream.println:(I)V 方法
生成新的栈帧(分配 locals、stack等)
传递参数,执行新栈帧中的字节码
执行完毕,弹出栈帧
清除 main 操作数栈内容
完成 main 方法调用,弹出 main 栈帧
程序结束
上一篇:HTTP服务器