字节码
编译+简单查看字节码
字节码
javac -g x.java 添加一个参数g可以在查看字节码文件时看到本地方法表
javap -c -verbose x.class 添加一个参数可以查看常量池 行号 头
load 间给本地变量表的数据写入到栈中,
store将栈中的数据写入到本地变量表中
这里有两个方法体,第一个中是一个构造方法
aload_0将本地常量池中零为的操作数压入栈中
调用invokespecial指令,操作数是#1即调用本地常量池中 序号为1 的指令,即调用父类的Object类的初始h化方法
主函数中
获取静态类 此处对应着获取了一个I/O类的PrintScream类 其后跟两位操作数
一个String类型
调用方法 调用PrintScream类的prinln方法
C:\Users\DELL\Desktop\商城项目\untitled\src>javac -g HelloWorld.java
任务一
C:\Users\DELL\Desktop\商城项目\untitled\src>javap -c -verbose HelloWorld
Classfile /C:/Users/DELL/Desktop/商城项目/untitled/src/HelloWorld.class
Last modified 2021年1月7日; size 689 bytes
//时间戳,字节大小
MD5 checksum 012ea257eb83031171c7bc41bbeb21aa
Compiled from "HelloWorld.java"
public class HelloWorld
minor version: 0
major version: 53
//代表jdk8
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #2 // HelloWorld
super_class: #8 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
//两个方法,一个main方法,一个
Constant pool:
#1 = Methodref #8.#36 // java/lang/Object."<init>":()V
#2 = Class #37 // HelloWorld
#3 = Methodref #2.#36 // HelloWorld."<init>":()V
#4 = Long 3l
#6 = Double 1.55d
#8 = Class #38 // java/lang/Object
#9 = Utf8 <init>
#10 = Utf8 ()V
#11 = Utf8 Code
#12 = Utf8 LineNumberTable
#13 = Utf8 LocalVariableTable
#14 = Utf8 this
#15 = Utf8 LHelloWorld;
#16 = Utf8 main
#17 = Utf8 ([Ljava/lang/String;)V
#18 = Utf8 i
#19 = Utf8 I
#20 = Utf8 args
#21 = Utf8 [Ljava/lang/String;
#22 = Utf8 helloWorld
#23 = Utf8 m
#24 = Utf8 f
#25 = Utf8 F
#26 = Utf8 l
#27 = Utf8 J
#28 = Utf8 c
#29 = Utf8 C
#30 = Utf8 s
#31 = Utf8 D
#32 = Utf8 StackMapTable
#33 = Class #21 // "[Ljava/lang/String;"
#34 = Utf8 SourceFile
#35 = Utf8 HelloWorld.java
#36 = NameAndType #9:#10 // "<init>":()V
#37 = Utf8 HelloWorld
#38 = Utf8 java/lang/Object
{
public HelloWorld();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
//栈深为1,本地变量表中有一个 就是当前这个类
0: aload_0
//将常量池中#0压栈
1: invokespecial #1 // Method java/lang/Object."<init>":()V
//常量池#1的指令 调用Object类的init方法
4: return
LineNumberTable:
line 1: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LHelloWorld;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=10, args_size=1
0: new #2 // class HelloWorld
3: dup
//复制栈顶指针
4: invokespecial #3 // Method "<init>":()V
7: astore_1
//将HellWord类存入本地变量表
8: iconst_1
//当int取值-1~5时,JVM采用iconst指令将常量压入栈中
9: istore_2
//弹出栈顶元素,添加到本地变量表2的位置
10: fconst_1
//f 1 入栈
11: fstore_3
//保存在3的位置
12: ldc2_w #4 // long 3l
//此处可看到 long型的3l是存在常量池中的
15: lstore 4
//存储到本地变量表序号为4的位置
17: bipush 99
19: istore 6
21: ldc2_w #6 // double 1.55d
24: dstore 7
//本地常量表中2的元素入栈
26: iload_2
//数值5入栈
27: iconst_5
//弹出比较栈顶两个值,如果栈顶小则执行,否则跳的34行
28: if_icmple 34
31: iinc 2, 1
//位于slot=2位置的m +1
34: iconst_0
//将0压入到栈中
35: istore 9
将i弹出栈 存入本地变量表slot=9的位置处
37: iload 9
//slot = 9 处的i入栈
39: iconst_5
//常量5压栈
40: if_icmpge 58
//弹出两个数比较如果栈顶大的执行
43: iconst_5
//将5压栈 此处的5是3+2直接运行后的结果
44: istore_2
45: iconst_1
46: istore_2
47: bipush 6
49: istore_2
50: iconst_1
51: istore_2
52: iinc 9, 1
55: goto 37
58: return
LineNumberTable:
line 3: 0
line 4: 8
line 5: 10
line 6: 12
line 7: 17
line 8: 21
line 9: 26
line 10: 31
line 12: 34
line 13: 43
line 14: 45
line 15: 47
line 16: 50
line 12: 52
line 21: 58
LocalVariableTable:
Start Length Slot Name Signature
37 21 9 i I
0 59 0 args [Ljava/lang/String;
8 51 1 helloWorld LHelloWorld;
10 49 2 m I
12 47 3 f F
17 42 4 l J
21 38 6 c C
26 33 7 s D
StackMapTable: number_of_entries = 3
frame_type = 255 /* full_frame */
offset_delta = 34
locals = [ class "[Ljava/lang/String;", class HelloWorld, int, float, long, int, double ]
//排序方式参照常量表中的start
stack = []
frame_type = 252 /* append */
offset_delta = 2
locals = [ int ]
frame_type = 250 /* chop */
offset_delta = 20
}