java字节码解析学习
java字节码表
java源码:
public class TestByteCode {
public static void test() {
int a = 10;
int b = 10;
int c = (a+b)*10;
System.out.println(c);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = new String("aaaa");
test();
}
}
编译出的class通过javap -c TestByteCode.class解析出的字节码:
public class com.learn.test.code.bytecode.TestByteCode {
public com.learn.test.code.bytecode.TestByteCode();
/*这段是构造函数*/
Code:
/*加载了操作数栈中栈顶的引用*/
0: aload_0
/*invokespecial指的是调用父类的构造方法,完成实例初始化,#1是构造方法地址,应该指向方法区*/
1: invokespecial #1 // Method java/lang/Object."<init>":()V
/*返回空,如果是ireturn就是返回int,areturn返回引用,lreturn返回long型*/
4: return
/*test方法部分字节码*/
public static void test();
Code:
0: bipush 10 /*把int型的10push到操作树栈栈顶*/
2: istore_0 /*把栈顶的10出栈存放到局部变量表中的0号变量*/
3: bipush 10 /*把int型的10push到操作树栈栈顶*/
5: istore_1 /*把栈顶的int型的10出栈存放到局部变量表中的0号变量*/
6: iload_0 /*加载int型的0号局部标量到栈顶*/
7: iload_1 /*加载int型的1号局部标量到栈顶*/
8: iadd /*把栈顶的两元素弹出并相加放到栈顶*/
9: bipush 10 /*把int型的10压到栈顶*/
11: imul /*把栈顶的两元素弹出并相乘放到栈顶*/
12: istore_2 /*把栈顶的int型数据出栈存放到局部变量表中的2号变量*/
/*getStatic获得指定类的静态域,并将值压如栈顶,#2为地址*/
13: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
16: iload_2 /*把局部变量表中的2号变量加载到栈顶*/
/*invokevitual 调用实例方法*/
17: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
20: return /*返回空*/
public static void main(java.lang.String[]);
Code:
0: new #4 // class java/lang/String /*创建一个对象并压入栈顶*/
3: dup /*复制栈顶数值并将复制值压入栈顶*/
4: ldc #5 // String aaaa /*将 int, float 或 String 型常量值从常量池中推送至栈顶*/
/*invokespecial调用构造函数,调用String的构造函数*/
6: invokespecial #6 // Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1 /*把引用存放到当前栈帧的1号局部变量*/
10: invokestatic #7 // Method test:()V /*调用静态方法*/
13: return
}
常用的Java字节码指令有:
- 加载到操作数栈
bipush 加载常量到操作数栈顶
iload 将int型局部变量加载到栈顶
lload 将long型局部变量加载到栈顶
iconst_0 将int型0加载到栈顶
fconst_0 将float型加载到栈顶
ldc 加载常量池中数据到栈中 - 存储
istore 将栈顶int出栈并存放到局部变量中
fstore 将栈顶float出栈并存放到局部变量中 - 计算
iadd ladd fadd dadd 栈顶两操作数操作,int或long等,结果压栈顶
isub lsub fsub dsub 减法
imul lmul fmul 乘法
idiv ldiv fdiv 除法
irem lrem 取模
ineg lneg 取非
ishl 左位移
ifeq ifne 比较 - 调用相关
getstatic 获取指定类的静态域,并入栈
invokespecial 调用超类构造方法,实例初始化方法,私有方法。
invokestatic 调用静态方法。
“invokeinterface” 调用接口方法。
invokedynamic 调用动态链接方法 - 内存分配
new 创建一个对象,并将其引用值压入栈顶。
newarray 创建一个指定原始类型(如 int、 float、 char??)的数组,并将其引用值压入栈顶 - 返回
ireturn 从当前方法返回 int。
lreturn 从当前方法返回 long。
freturn 从当前方法返回 float。
有了这些基本能读懂些字节码了
还没有评论,来说两句吧...