一、什么是javap
javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具。
javap - Java class文件分解器
分解class文件
摘要:
javap [ options ] class. . .
描述:
javap命令分解一个class文件,它根据options来决定到底输出什么。如果没有使用options,那么javap将会输出包,类里的protected和public域以及类里的所有方法。javap将会把它们输出在标准输出上。来看这个例子,先编译下面这个类。
Java代码
import java.awt.*;
import java.applet.*;
public class DocFooter extends Applet {
String date;
String email;
public void init() {
resize(500,100);
date = getParameter("LAST_UPDATED");
email = getParameter("EMAIL");
}
public void paint(Graphics g) {
g.drawString(date + " by ",100, 15);
g.drawString(email,290,15);
}
}
在命令行上键入javap DocFooter后,输出结果如下
Java代码
Compiled from DocFooter.java
public class DocFooter extends java.applet.Applet {
java.lang.String date;
java.lang.String email;
public DocFooter();
public void init();
public void paint(java.awt.Graphics);
}
如果加入了-c,即javap -c DocFooter,那么输出结果如下
Java代码
Compiled from DocFooter.java
public class DocFooter extends java.applet.Applet {
java.lang.String date;
java.lang.String email;
public DocFooter();
public void init();
public void paint(java.awt.Graphics);
}
Method DocFooter()
0 aload_0
1 invokespecial #1
4 return
Method void init()
0 aload_0
1 sipush 500
4 bipush 100
6 invokevirtual #2
9 aload_0
10 aload_0
11 ldc #3
13 invokevirtual #4
16 putfield #5
19 aload_0
20 aload_0
21 ldc #6
23 invokevirtual #4
26 putfield #7
29 return
Method void paint(java.awt.Graphics)
0 aload_1
1 new #8
4 dup
5 invokespecial #9
8 aload_0
9 getfield #5
12 invokevirtual #10
15 ldc #11
17 invokevirtual #10
20 invokevirtual #12
23 bipush 100
25 bipush 15
27 invokevirtual #13
30 aload_1
31 aload_0
32 getfield #7
35 sipush 290
38 bipush 15
40 invokevirtual #13
43 return
当然,如果想分析这个文件,可以讲输出结果输出到一个文件里。可以这样写
javap -c DocFooter > F://test.txt
这样就会输出到F盘的test.txt文件中了。
选项:
-help 帮助
-l 输出行和变量的表
-public 只输出public方法和域
-protected 只输出public和protected类和成员
-package 只输出包,public和protected类和成员,这是默认的
-p -private 输出所有类和成员
-s 输出内部类型签名
-c 输出分解后的代码,例如,类中每一个方法内,包含java字节码的指令,
-verbose 输出栈大小,方法参数的个数
-constants 输出静态final常量
二、栈和局部变量操作
将常量压入栈的指令
aconst_null
iconst_m1
iconst_0
iconst_1
iconst_2
iconst_3
iconst_4
iconst_5
lconst_0
lconst_1
fconst_0
fconst_1
dconst_0
dconst_1
bipush
sipush
ldc
ldc_w
ldc2_w
从栈中的局部变量中装载值的指令
iload
lload
fload
dload
aload
iload_0
iload_1
iload_2
iload_3
lload_0
lload_1
lload_2
lload_3
fload_0
fload_1
fload_2
fload_3
dload_0
dload_1
dload_2
dload_3
aload_0
aload_1
aload_2
aload_3
iaload
laload
faload
daload
aaload
baload
caload
saload
将栈中的值存入局部变量的指令
istore
lstore
fstore
dstore
astore
istore_0
istore_1
istore_2
istore_3
lstore_0
lstore_1
lstore_2
lstore_3
fstore_0
fstore_1
fstore_2
fstore_3
dstore_0
dstore_1
dstore_2
dstore_3
astore_0
astore_1
astore_2
astore_3
iastore
lastore
fastore
dastore
aastore
bastore
castore
sastore
wide指令
wide
通用(无类型)栈操作
nop
pop
pop2
dup
dup_x1
dup_x2
dup2
dup2_x1
dup2_x2
swap
类型转换
i2l
i2f
i2d
l2i
l2f
l2d
f2i
f2l
f2d
d2i
d2l
d2f
i2b
i2c
i2s
整数运算
iadd
ladd
isub
lsub
imul
lmul
idiv
ldiv
irem
lrem
ineg
lneg
iinc
逻辑运算
移位操作
ishl
lshl
ishr
lshr
iushr
lushr
按位布尔运算
iand
land
ior
lor
ixor
lxor
浮点运算
fadd
dadd
fsub
dsub
fmul
dmul
fdiv
ddiv
frem
drem
fneg
dneg
对象和数组
对象操作指令
new
checkcast
getfield
putfield
getstatic
putstatic
instanceof
数组操作指令
newarray
anewarray
arraylength
multianewarray
控制流
条件分支指令
ifeq
ifne
iflt
ifge
ifgt
ifle
if_icmpcq
if_icmpne
if_icmplt
if_icmpge
if_icmpgt
if_icmple
ifnull
ifnonnull
if_acmpeq
if_acmpnc
比较指令
lcmp
fcmpl
fcmpg
dcmpl
dcmpg
无条件转移指令
goto
goto_w
表跳转指令
tableswitch
lookupswitch
异常
athrow
finally子句
jsr
jsr_w
rct
方法调用与返回
方法调用指令
invokcvirtual
invokespecial
invokestatic
invokcinterface
方法返回指令
ireturn
lreturn
freturn
dreturn
areturn
return
线程同步
montiorenter
monitorexit
***********************************************************************
JVM指令助记符
变量到操作数栈:iload,iload_,lload,lload_,fload,fload_,dload,dload_,aload,aload_
操作数栈到变量:istore,istore_,lstore,lstore_,fstore,fstore_,dstore,dstor_,astore,astore_
常数到操作数栈:bipush,sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_ml,iconst_,lconst_,fconst_,dconst_
加:iadd,ladd,fadd,dadd
减:isub,lsub,fsub,dsub
乘:imul,lmul,fmul,dmul
除:idiv,ldiv,fdiv,ddiv
余数:irem,lrem,frem,drem
取负:ineg,lneg,fneg,dneg
移位:ishl,lshr,iushr,lshl,lshr,lushr
按位或:ior,lor
按位与:iand,land
按位异或:ixor,lxor
类型转换:i2l,i2f,i2d,l2f,l2d,f2d(放宽数值转换)
创建类实便:new
创建新数组:newarray,anewarray,multianwarray
访问类的域和类实例域:getfield,putfield,getstatic,putstatic
把数据装载到操作数栈:baload,caload,saload,iaload,laload,faload,daload,aaload
从操作数栈存存储到数组:bastore,castore,sastore,iastore,lastore,fastore,dastore,aastore
获取数组长度:arraylength
检相类实例或数组属性:instanceof,checkcast
操作数栈管理:pop,pop2,dup,dup2,dup_xl,dup2_xl,dup_x2,dup2_x2,swap
有条件转移:ifeq,iflt,ifle,ifne,ifgt,ifge,ifnull,ifnonnull,if_icmpeq,if_icmpene,
复合条件转移:tableswitch,lookupswitch
无条件转移:goto,goto_w,jsr,jsr_w,ret
调度对象的实便方法:invokevirtual
调用由接口实现的方法:invokeinterface
调用需要特殊处理的实例方法:invokespecial
调用命名类中的静态方法:invokestatic
方法返回:ireturn,lreturn,freturn,dreturn,areturn,return
异常:athrow
finally关键字的实现使用:jsr,jsr_w,ret