Java中查看class文件指令:(亲测jdk1.8需要加文件后缀)
javap -c xxxx.class
javap -v xxx.class
javap -verbose xxx.class
可以直接使用java -?查询具体指令
-help --help -? 输出此用法消息
-version 版本信息
-v -verbose 输出附加信息
-l 输出行号和本地变量表
-public 仅显示公共类和成员
-protected 显示受保护的/公共类和成员
-package 显示程序包/受保护的/公共类和成员 (默认)
-p -private 显示所有类和成员
-c 对代码进行反汇编
...
如下是jvm指令集:
助记符 | 操作码 | [操作数数量]:[操作数列表] | 栈数据变化 | 描述 | 中文 |
---|---|---|---|---|---|
nop | 0x00 | [No change] | perform no operation | 不执行任何操作 | |
aconst_null | 0x01 | → null | push a null reference onto the stack | 将null存入栈中 | |
iconst_m1 | 0x02 | → -1 | load the int value −1 onto the stack | 将int型-1存入栈中 | |
iconst_0 | 0x03 | → 0 | load the int value 0 onto the stack | 将int型0存入栈中 | |
iconst_1 | 0x04 | → 1 | load the int value 1 onto the stack | 将int型1存入栈中 | |
iconst_2 | 0x05 | → 2 | load the int value 2 onto the stack | 将int型2存入栈中 | |
iconst_3 | 0x06 | → 3 | load the int value 3 onto the stack | 将int型3存入栈中 | |
iconst_4 | 0x07 | → 4 | load the int value 4 onto the stack | 将int型4存入栈中 | |
iconst_5 | 0x08 | → 5 | load the int value 5 onto the stack | 将int型5存入栈中 | |
lconst_0 | 0x09 | → 0L | push 0L (the number zero with type long) onto the stack | 将long型0存入栈中 | |
lconst_1 | 0x0a | → 1L | push 1L (the number one with type long) onto the stack | 将long型1存入栈中 | |
fconst_0 | 0x0b | → 0.0f | push 0.0f on the stack | 将float型0存入栈中 | |
fconst_1 | 0x0c | → 1.0f | push 1.0f on the stack | 将float型1存入栈中 | |
fconst_2 | 0x0d | → 2.0f | push 2.0f on the stack | 将float型2存入栈中 | |
dconst_0 | 0x0e | → 0.0 | push the constant 0.0 (a double) onto the stack | 将double型0.0存入栈中 | |
dconst_1 | 0x0f | → 1.0 | push the constant 1.0 (a double) onto the stack | 将double型1.0存入栈中 | |
bipush | 0x10 | 1: byte | → value | push a byte onto the stack as an integer value | 将指定byte值(-27~27-1)作为int型值存入栈中 |
sipush | 0x11 | 2: byte1, byte2 | → value | push a short onto the stack as an integer value | 将指定short值(-215~215-1)作为int型值存入栈中 |
ldc | 0x12 | 1: index | → value | push a constant #index from a constant pool (String, int, float, Class, java.lang.invoke.MethodType, or java.lang.invoke.MethodHandle) onto the stack | 从常量池(String, int, float, Class, MethodType, MethodHandle)加载指定值到栈中 |
ldc_w | 0x13 | 2: indexbyte1, indexbyte2 | → value | push a constant #index from a constant pool (String, int, float, Class, java.lang.invoke.MethodType, or java.lang.invoke.MethodHandle) onto the stack (wide index is constructed as indexbyte1 << 8 + indexbyte2) | 从常量池(String, int, float, Class, MethodType, MethodHandle)加载指定值到栈中(索引宽度构造为indexbyte1 << 8 + indexbyte2) |
ldc2_w | 0x14 | 2: indexbyte1, indexbyte2 | → value | push a constant #index from a constant pool (double or long) onto the stack (wide index is constructed as indexbyte1 << 8 + indexbyte2) | 从常量池(double,long)加载指定值到栈中(索引宽度构造为indexbyte1 << 8 + indexbyte2) |
iload | 0x15 | 1: index | → value | load an int value from a local variable #index | 将本地指定的int型值存入栈中 |
lload | 0x16 | 1: index | → value | load a long value from a local variable #index | 将本地指定的long型值存入栈中 |
fload | 0x17 | 1: index | → value | load a float value from a local variable #index | 将本地指定的float型值存入栈中 |
dload | 0x18 | 1: index | → value | load a double value from a local variable #index | 将本地指定的double型值存入栈中 |
aload | 0x19 | 1: index | → objectref | load a reference onto the stack from a local variable #index | 将本地指定的引用存入栈中 |
iload_0 | 0x1a | → value | load an int value from local variable 0 | 将第0个本地int值存入栈中 | |
iload_1 | 0x1b | → value | load an int value from local variable 1 | 将第1个本地int值存入栈中 | |
iload_2 | 0x1c | → value | load an int value from local variable 2 | 将第2个本地int值存入栈中 | |
iload_3 | 0x1d | → value | load an int value from local variable 3 | 将第3个本地int值存入栈中 | |
lload_0 | 0x1e | → value | load a long value from a local variable 0 | 将第0个本地long 值存入栈中 | |
lload_1 | 0x1f | → value | load a long value from a local variable 1 | 将第1个本地long 值存入栈中 | |
lload_2 | 0x20 | → value | load a long value from a local variable 2 | 将第2个本地long 值存入栈中 | |
lload_3 | 0x21 | → value | load a long value from a local variable 3 | 将第3个本地long 值存入栈中 | |
fload_0 | 0x22 | → value | load a float value from local variable 0 | 将第0个本地float 值存入栈中 | |
fload_1 | 0x23 | → value | load a float value from local variable 1 | 将第1个本地float 值存入栈中 | |
fload_2 | 0x24 | → value | load a float value from local variable 2 | 将第2个本地float 值存入栈中 | |
fload_3 | 0x25 | → value | load a float value from local variable 3 | 将第3个本地float 值存入栈中 | |
dload_0 | 0x26 | → value | load a double from local variable 0 | 将第0个本地double值存入栈中 | |
dload_1 | 0x27 | → value | load a double from local variable 1 | 将第1个本地double值存入栈中 | |
dload_2 | 0x28 | → value | load a double from local variable 2 | 将第2个本地double值存入栈中 | |
dload_3 | 0x29 | → value | load a double from local variable 3 | 将第3个本地double值存入栈中 | |
aload_0 | 0x2a | → objectref | load a reference onto the stack from local variable 0 | 将第0个本地引用存入栈中 | |
aload_1 | 0x2b | → objectref | load a reference onto the stack from local variable 1 | 将第1个本地引用存入栈中 | |
aload_2 | 0x2c | → objectref | load a reference onto the stack from local variable 2 | 将第2个本地引用存入栈中 | |
aload_3 | 0x2d | → objectref | load a reference onto the stack from local variable 3 | 将第3个本地引用存入栈中 | |
iaload | 0x2e | arrayref, index → value | load an int from an array | 将int型数组指定索引的值存入栈中 | |
laload | 0x2f | arrayref, index → value | load a long from an array | 将long型数组指定索引的值存入栈中 | |
faload | 0x30 | arrayref, index → value | load a float from an array | 将float型数组指定索引的值存入栈中 | |
daload | 0x31 | arrayref, index → value | load a double from an array | 将double型数组指定索引的值存入栈中 | |
aaload | 0x32 | arrayref, index → value | load onto the stack a reference from an array | 将引用型数组指定索引的值存入栈中 | |
baload | 0x33 | arrayref, index → value | load a byte or Boolean value from an array | 将byte/Boolean型数组指定索引的值存入栈中 | |
caload | 0x34 | arrayref, index → value | load a char from an array | 将char型数组指定索引的值存入栈中 | |
saload | 0x35 | arrayref, index → value | load short from array | 将short型数组指定索引的值存入栈中 | |
istore | 0x36 | 1: index | value → | store int value into variable #index | 将栈顶int值存入指定变量 |
lstore | 0x37 | 1: index | value → | store a long value in a local variable #index | 将栈顶long值存入指定本地变量 |
fstore | 0x38 | 1: index | value → | store a float value into a local variable #index | 将栈顶float值存入指定本地变量 |
dstore | 0x39 | 1: index | value → | store a double value into a local variable #index | 将栈顶double值存入指定本地变量 |
astore | 0x3a | 1: index | objectref → | store a reference into a local variable #index | 将栈顶引用型值存入指定本地变量 |
istore_0 | 0x3b | value → | store int value into variable 0 | 将栈顶int值存入第0个本地变量 | |
istore_1 | 0x3c | value → | store int value into variable 1 | 将栈顶int值存入第1个本地变量 | |
istore_2 | 0x3d | value → | store int value into variable 2 | 将栈顶int值存入第2个本地变量 | |
istore_3 | 0x3e | value → | store int value into variable 3 | 将栈顶int值存入第3个本地变量 | |
lstore_0 | 0x3f | value → | store a long value in a local variable 0 | 将栈顶long值存入第0个本地变量 | |
lstore_1 | 0x40 | value → | store a long value in a local variable 1 | 将栈顶long值存入第1个本地变量 | |
lstore_2 | 0x41 | value → | store a long value in a local variable 2 | 将栈顶long值存入第2个本地变量 | |
lstore_3 | 0x42 | value → | store a long value in a local variable 3 | 将栈顶long值存入第3个本地变量 | |
fstore_0 | 0x43 | value → | store a float value into local variable 0 | 将栈顶float值存入第0个本地变量 | |
fstore_1 | 0x44 | value → | store a float value into local variable 1 | 将栈顶float值存入第1个本地变量 | |
fstore_2 | 0x45 | value → | store a float value into local variable 2 | 将栈顶float值存入第2个本地变量 | |
fstore_3 | 0x46 | value → | store a float value into local variable 3 | 将栈顶float值存入第3个本地变量 | |
dstore_0 | 0x47 | value → | store a double into local variable 0 | 将栈顶double值存入第0个本地变量 | |
dstore_1 | 0x48 | value → | store a double into local variable 1 | 将栈顶double值存入第1个本地变量 | |
dstore_2 | 0x49 | value → | store a double into local variable 2 | 将栈顶double值存入第2个本地变量 | |
dstore_3 | 0x4a | value → | store a double into local variable 3 | 将栈顶double值存入第3个本地变量 | |
astore_0 | 0x4b | objectref → | store a reference into local variable 0 | 将栈顶引用值存入第0个本地变量 | |
astore_1 | 0x4c | objectref → | store a reference into local variable 1 | 将栈顶引用值存入第1个本地变量 | |
astore_2 | 0x4d | objectref → | store a reference into local variable 2 | 将栈顶引用值存入第2个本地变量 | |
astore_3 | 0x4e | objectref → | store a reference into local variable 3 | 将栈顶引用值存入第3个本地变量 | |
iastore | 0x4f | arrayref, index, value → | store an int into an array | 将栈顶int值存入指定数组指定索引位置 | |
lastore | 0x50 | arrayref, index, value → | store a long to an array | 将栈顶long值存入指定数组指定索引位置 | |
fastore | 0x51 | arrayref, index, value → | store a float in an array | 将栈顶float值存入指定数组指定索引位置 | |
dastore | 0x52 | arrayref, index, value → | store a double into an array | 将栈顶double值存入指定数组指定索引位置 | |
aastore | 0x53 | arrayref, index, value → | store into a reference in an array | 将栈顶引用型值存入指定数组指定索引位置 | |
bastore | 0x54 | arrayref, index, value → | store a byte or Boolean value into an array | 将栈顶byte/boolean值存入指定数组指定索引位置 | |
castore | 0x55 | arrayref, index, value → | store a char into an array | 将栈顶char值存入指定数组指定索引位置 | |
sastore | 0x56 | arrayref, index, value → | store short to array | 将栈顶short值存入指定数组指定索引位置 | |
pop | 0x57 | value → | discard the top value on the stack | 弹出栈顶的值 | |
pop2 | 0x58 | {value2, value1} → | discard the top two values on the stack (or one value, if it is a double or long) | 丢弃栈顶的前两个值(如果是double或long则弹出一个) | |
dup | 0x59 | value → value, value | duplicate the value on top of the stack | 复制栈顶的值并存入栈顶 | |
dup_x1 | 0x5a | value2, value1 → value1, value2, value1 | insert a copy of the top value into the stack two values from the top. value1 and value2 must not be of the type double or long. | 复制栈顶的两个值并存入栈中(栈顶的两个值不能为double/long) | |
dup_x2 | 0x5b | value3, value2, value1 → value1, value3, value2, value1 | insert a copy of the top value into the stack two (if value2 is double or long it takes up the entry of value3, too) or three values (if value2 is neither double nor long) from the top | 复制栈顶的两个(第二个值为double/long)或者三个(第二个值不是double/long)值并存入栈中 | |
dup2 | 0x5c | {value2, value1} → {value2, value1}, {value2, value1} | duplicate top two stack words (two values, if value1 is not double nor long; a single value, if value1 is double or long) | 复制栈顶的两个单词到栈中(非double/long为两个单词,double/long为一个单词) | |
dup2_x1 | 0x5d | value3, {value2, value1} → {value2, value1}, value3, {value2, value1} | duplicate two words and insert beneath third word (see explanation above) | 复制栈顶的两个单词并插入到第三个词下面(非double/long为两个单词,double/long为一个单词) | |
dup2_x2 | 0x5e | {value4, value3}, {value2, value1} → {value2, value1}, {value4, value3}, {value2, value1} | duplicate two words and insert beneath fourth word | 复制两个单词并插入到第四个单词下(非double/long为两个单词,double/long为一个单词) | |
swap | 0x5f | value2, value1 → value1, value2 | swaps two top words on the stack (note that value1 and value2 must not be double or long) | 交换栈顶的两个值(两个值不能为long/double) | |
iadd | 0x60 | value1, value2 → result | add two ints | 对栈顶两个int相加后存入栈中 | |
ladd | 0x61 | value1, value2 → result | add two longs | 对栈顶两个long相加后存入栈中 | |
fadd | 0x62 | value1, value2 → result | add two floats | 对栈顶两个float相加后存入栈中 | |
dadd | 0x63 | value1, value2 → result | add two doubles | 对栈顶两个double相加后存入栈中 | |
isub | 0x64 | value1, value2 → result | int subtract | 对栈顶两个int相减后存入栈中 | |
lsub | 0x65 | value1, value2 → result | subtract two longs | 对栈顶两个long相减后存入栈中 | |
fsub | 0x66 | value1, value2 → result | subtract two floats | 对栈顶两个float相减后存入栈中 | |
dsub | 0x67 | value1, value2 → result | subtract a double from another | 对栈顶两个double相减后存入栈中 | |
imul | 0x68 | value1, value2 → result | multiply two integers | 对栈顶两个int相乘后存入栈中 | |
lmul | 0x69 | value1, value2 → result | multiply two longs | 对栈顶两个long相乘后存入栈中 | |
fmul | 0x6a | value1, value2 → result | multiply two floats | 对栈顶两个float相乘后存入栈中 | |
dmul | 0x6b | value1, value2 → result | multiply two doubles | 对栈顶两个double相乘后存入栈中 | |
idiv | 0x6c | value1, value2 → result | divide two integers | 对栈顶两个int相除后存入栈中 | |
ldiv | 0x6d | value1, value2 → result | divide two longs | 对栈顶两个long相除后存入栈中 | |
fdiv | 0x6e | value1, value2 → result | divide two floats | 对栈顶两个float相除后存入栈中 | |
ddiv | 0x6f | value1, value2 → result | divide two doubles | 对栈顶两个double相除后存入栈中 | |
irem | 0x70 | value1, value2 → result | logical int remainder | 对栈顶两int取余后存入栈中 | |
lrem | 0x71 | value1, value2 → result | remainder of division of two longs | 对栈顶两long取余后存入栈中 | |
frem | 0x72 | value1, value2 → result | get the remainder from a division between two floats | 对栈顶两float取余后存入栈中 | |
drem | 0x73 | value1, value2 → result | get the remainder from a division between two doubles | 将栈顶两double取余的结果存入栈中 | |
ineg | 0x74 | value → result | negate int | 将栈顶的int的负值存入栈中 | |
lneg | 0x75 | value → result | negate a long | 将栈顶的long的负值存入栈中 | |
fneg | 0x76 | value → result | negate a float | 将栈顶的float的负值存入栈中 | |
dneg | 0x77 | value → result | negate a double | 将栈顶的double的负值存入栈中 | |
ishl | 0x78 | value1, value2 → result | int shift left | 将int值左移value2位 | |
lshl | 0x79 | value1, value2 → result | bitwise shift left of a long value1 by int value2 positions | 将long(value1)左移int(value2)位 | |
ishr | 0x7a | value1, value2 → result | int arithmetic shift right | 将int带符号右移value2位 | |
lshr | 0x7b | value1, value2 → result | bitwise shift right of a long value1 by int value2 positions | 将long(value1)带符号右移int(value2)位 | |
iushr | 0x7c | value1, value2 → result | int logical shift right | 将int(value1)无符号右移int(value2)位 | |
lushr | 0x7d | value1, value2 → result | bitwise shift right of a long value1 by int value2 positions, unsigned | 将long(value1)无符号右移int(value2)位 | |
iand | 0x7e | value1, value2 → result | perform a bitwise AND on two integers | 两个int按位与 | |
land | 0x7f | value1, value2 → result | bitwise AND of two longs | 两个long按位与 | |
ior | 0x80 | value1, value2 → result | bitwise int OR | 两个int按位或 | |
lor | 0x81 | value1, value2 → result | bitwise OR of two longs | 两个long按位或 | |
ixor | 0x82 | value1, value2 → result | int xor | 两个int按位异或 | |
lxor | 0x83 | value1, value2 → result | bitwise XOR of two longs | 两个long按位异或 | |
iinc | 0x84 | 2: index, const | [No change] | increment local variable #index by signed byte const | 将第index个int增加const |
i2l | 0x85 | value → result | convert an int into a long | 将int转换为long | |
i2f | 0x86 | value → result | convert an int into a float | 将int转换为float | |
i2d | 0x87 | value → result | convert an int into a double | 将int转换为double | |
l2i | 0x88 | value → result | convert a long to a int | 将long转换为int | |
l2f | 0x89 | value → result | convert a long to a float | 将long转换为float | |
l2d | 0x8a | value → result | convert a long to a double | 将long转换为double | |
f2i | 0x8b | value → result | convert a float to an int | 将float转换为int | |
f2l | 0x8c | value → result | convert a float to a long | 将float转换为long | |
f2d | 0x8d | value → result | convert a float to a double | 将float转换为double | |
d2i | 0x8e | value → result | convert a double to an int | 将double转换为int | |
d2l | 0x8f | value → result | convert a double to a long | 将double转换为long | |
d2f | 0x90 | value → result | convert a double to a float | 将double转换为float | |
i2b | 0x91 | value → result | convert an int into a byte | 将int转换为byte | |
i2c | 0x92 | value → result | convert an int into a character | 将int转换为char | |
i2s | 0x93 | value → result | convert an int into a short | 将int转换为short | |
lcmp | 0x94 | value1, value2 → result | push 0 if the two longs are the same, 1 if value1 is greater than value2, -1 otherwise | 比较两个long值(value1=value2为0;value1>value2为1;value1<value2为-1) | |
fcmpl | 0x95 | value1, value2 → result | compare two floats | 比较两个float值(value1=value2为0;value1>value2为1;value1<value2为-1);当其中一个为NaN时为-1 | |
fcmpg | 0x96 | value1, value2 → result | compare two floats | 比较两个float值(value1=value2为0;value1>value2为1;value1<value2为-1);当其中一个为NaN时为1 | |
dcmpl | 0x97 | value1, value2 → result | compare two doubles | 比较两个double值(value1=value2为0;value1>value2为1;value1<value2为-1);当其中一个为NaN时为-1 | |
dcmpg | 0x98 | value1, value2 → result | compare two doubles | 比较两个float值(value1=value2为0;value1>value2为1;value1<value2为-1);当其中一个为NaN时为1 | |
ifeq | 0x99 | 2: branchbyte1, branchbyte2 | value → | if value is 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果栈顶值为0跳转 |
ifne | 0x9a | 2: branchbyte1, branchbyte2 | value → | if value is not 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果栈顶值!=0跳转 |
iflt | 0x9b | 2: branchbyte1, branchbyte2 | value → | if value is less than 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果栈顶值<0跳转 |
ifge | 0x9c | 2: branchbyte1, branchbyte2 | value → | if value is greater than or equal to 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果栈顶值>=0跳转 |
ifgt | 0x9d | 2: branchbyte1, branchbyte2 | value → | if value is greater than 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果栈顶值>0跳转 |
ifle | 0x9e | 2: branchbyte1, branchbyte2 | value → | if value is less than or equal to 0, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果栈顶值<=0跳转 |
if_icmpeq | 0x9f | 2: branchbyte1, branchbyte2 | value1, value2 → | if ints are equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果两个int值相等跳转 |
if_icmpne | 0xa0 | 2: branchbyte1, branchbyte2 | value1, value2 → | if ints are not equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果两个int值不相等跳转 |
if_icmplt | 0xa1 | 2: branchbyte1, branchbyte2 | value1, value2 → | if value1 is less than value2, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果value1<value2跳转(两个值均为int) |
if_icmpge | 0xa2 | 2: branchbyte1, branchbyte2 | value1, value2 → | if value1 is greater than or equal to value2, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果value1>=value2跳转(两个值均为int) |
if_icmpgt | 0xa3 | 2: branchbyte1, branchbyte2 | value1, value2 → | if value1 is greater than value2, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果value1>value2跳转(两个值均为int) |
if_icmple | 0xa4 | 2: branchbyte1, branchbyte2 | value1, value2 → | if value1 is less than or equal to value2, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 当value1<=value2是跳转(两个值均为int) |
if_acmpeq | 0xa5 | 2: branchbyte1, branchbyte2 | value1, value2 → | if references are equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果两个引用值相等跳转 |
if_acmpne | 0xa6 | 2: branchbyte1, branchbyte2 | value1, value2 → | if references are not equal, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 如果两个引用值不相等跳转 |
goto | 0xa7 | 2: branchbyte1, branchbyte2 | [no change] | goes to another instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | 无条件跳转 |
jsr | 0xa8 | 2: branchbyte1, branchbyte2 | → address | jump to subroutine at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) and place the return address on the stack | 跳转至指定位置的子程序,并将jsr下一条指令地址存入栈顶 |
ret | 0xa9 | 1: index | [No change] | continue execution from address taken from a local variable #index (the asymmetry with jsr is intentional) | 返回至本地变量指定的index的指令位置(一般与jsr, jsr_w联合使用) |
tableswitch | 0xaa | 16+: [0–3 bytes padding], defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, lowbyte1, lowbyte2, lowbyte3, lowbyte4, highbyte1, highbyte2, highbyte3, highbyte4, jump offsets... | index → | continue execution from an address in the table at offset index | 用于switch条件跳转,case值连续(可变长度指令) |
lookupswitch | 0xab | 8+: <0–3 bytes padding>, defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, npairs1, npairs2, npairs3, npairs4, match-offset pairs... | key → | a target address is looked up from a table using a key and execution continues from the instruction at that address | 用于switch条件跳转,case值不连续(可变长度指令) |
ireturn | 0xac | value → [empty] | return an integer from a method | 从当前方法返回int | |
lreturn | 0xad | value → [empty] | return a long value | 从当前方法返回long | |
freturn | 0xae | value → [empty] | return a float | 从当前方法返回float | |
dreturn | 0xaf | value → [empty] | return a double from a method | 从当前方法返回double | |
areturn | 0xb0 | objectref → [empty] | return a reference from a method | 从当前方法返回一个引用型值 | |
return | 0xb1 | → [empty] | return void from method | 从当前方法返回 | |
getstatic | 0xb2 | 2: indexbyte1, indexbyte2 | → value | get a static field value of a class, where the field is identified by field reference in the constant pool index (indexbyte1 << 8 + indexbyte2) | 获取类的静态字段,字段由常量池索引中的字段引用标识(indexbyte1 << 8 + indexbyte2) |
putstatic | 0xb3 | 2: indexbyte1, indexbyte2 | value → | set static field to value in a class, where the field is identified by a field reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 将静态字段设置为类中的值,字段由常量池索引中的字段引用标识(indexbyte1 << 8 + indexbyte2) |
getfield | 0xb4 | 2: indexbyte1, indexbyte2 | objectref → value | get a field value of an object objectref, where the field is identified by field reference in the constant pool index (indexbyte1 << 8 + indexbyte2) | 获取实例指定字段值 |
putfield | 0xb5 | 2: indexbyte1, indexbyte2 | objectref, value → | set field to value in an object objectref, where the field is identified by a field reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 为实例指定字段赋值 |
invokevirtual | 0xb6 | 2: indexbyte1, indexbyte2 | objectref, [arg1, arg2, ...] → result | invoke virtual method on object objectref and puts the result on the stack (might be void); the method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 调用实例虚方法,并将结果存入栈中 |
invokespecial | 0xb7 | 2: indexbyte1, indexbyte2 | objectref, [arg1, arg2, ...] → result | invoke instance method on object objectref and puts the result on the stack (might be void); the method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 调用实例方法,并将结果存入栈中 |
invokestatic | 0xb8 | 2: indexbyte1, indexbyte2 | [arg1, arg2, ...] → result | invoke a static method and puts the result on the stack (might be void); the method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 调用静态方法,并将结果存入栈中 |
invokeinterface | 0xb9 | 4: indexbyte1, indexbyte2, count, 0 | objectref, [arg1, arg2, ...] → result | invokes an interface method on object objectref and puts the result on the stack (might be void); the interface method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 调用接口方法,并将结果存入栈中 |
invokedynamic | 0xba | 4: indexbyte1, indexbyte2, 0, 0 | [arg1, [arg2 ...]] → result | invokes a dynamic method and puts the result on the stack (might be void); the method is identified by method reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 调用动态方法,并将结果存入栈中 |
new | 0xbb | 2: indexbyte1, indexbyte2 | → objectref | create new object of type identified by class reference in constant pool index (indexbyte1 << 8 + indexbyte2) | 创建一个类常量池中index为指定值的引用型值,并存入栈中 |
newarray | 0xbc | 1: atype | count → arrayref | create new array with count elements of primitive type identified by atype | 创建count长度的指定的基本类型数组 |
anewarray | 0xbd | 2: indexbyte1, indexbyte2 | count → arrayref | create a new array of references of length count and component type identified by the class reference index (indexbyte1 << 8 + indexbyte2) in the constant pool | 创建count长度的指定引用类型数组 |
arraylength | 0xbe | arrayref → length | get the length of an array | 获取数组长度 | |
athrow | 0xbf | objectref → [empty], objectref | throws an error or exception (notice that the rest of the stack is cleared, leaving only a reference to the Throwable) | 抛出异常(栈的其余部分已被清除,只留下对异常对象的引用) | |
checkcast | 0xc0 | 2: indexbyte1, indexbyte2 | objectref → objectref | checks whether an objectref is of a certain type, the class reference of which is in the constant pool at index (indexbyte1 << 8 + indexbyte2) | 检验类型转换,检验未通过将抛出ClassCastException |
instanceof | 0xc1 | 2: indexbyte1, indexbyte2 | objectref → result | determines if an object objectref is of a given type, identified by class reference index in constant pool (indexbyte1 << 8 + indexbyte2) | 检验对象是否是指定的类的实例 |
monitorenter | 0xc2 | objectref → | enter monitor for object ("grab the lock" – start of synchronized() section) | 获取对像监视控器(synchronized()的开始部分) | |
monitorexit | 0xc3 | objectref → | exit monitor for object ("release the lock" – end of synchronized() section) | 退出对象监视器(synchronized()的结束部分) | |
wide | 0xc4 | 3/5: opcode, indexbyte1, indexbyte2 or iinc, indexbyte1, indexbyte2, countbyte1, countbyte2 |
[same as for corresponding instructions] | execute opcode, where opcode is either iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret, but assume the index is 16 bit; or execute iinc, where the index is 16 bits and the constant to increment by is a signed 16 bit short | 执行操作码,其中操作码为iload、fload、aload、lload、dload、istore、fstore、astore、lstore、dstore或ret(但假设索引为16位);或者执行iinc,其中索引是16位,要增加的常量是一个带符号的16位short |
multianewarray | 0xc5 | 3: indexbyte1, indexbyte2, dimensions | count1, [count2,...] → arrayref | create a new array of dimensions dimensions of type identified by class reference in constant pool index (indexbyte1 << 8 + indexbyte2); the sizes of each dimension is identified by count1, [count2, etc.] | 创建一个指定长度指定泛型的数组 |
ifnull | 0xc6 | 2: branchbyte1, branchbyte2 | value → | if value is null, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | value为null时执行指令 |
ifnonnull | 0xc7 | 2: branchbyte1, branchbyte2 | value → | if value is not null, branch to instruction at branchoffset (signed short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2) | value不为null时执行指令 |
goto_w | 0xc8 | 4: branchbyte1, branchbyte2, branchbyte3, branchbyte4 | [no change] | goes to another instruction at branchoffset (signed int constructed from unsigned bytes branchbyte1 << 24 + branchbyte2 << 16 + branchbyte3 << 8 + branchbyte4) | 跳转到指定指令 |
jsr_w | 0xc9 | 4: branchbyte1, branchbyte2, branchbyte3, branchbyte4 | → address | jump to subroutine at branchoffset (signed int constructed from unsigned bytes branchbyte1 << 24 + branchbyte2 << 16 + branchbyte3 << 8 + branchbyte4) and place the return address on the stack | 跳转到子程序 |
breakpoint | 0xca | reserved for breakpoints in Java debuggers; should not appear in any class file | 预留给Java调试器中的断点;不应该出现在任何类文件中吗 | ||
(no name) | 0xcb-0xfd | these values are currently unassigned for opcodes and are reserved for future use | 这些值目前未分配给操作码,保留给将来使用 | ||
impdep1 | 0xfe | reserved for implementation-dependent operations within debuggers; should not appear in any class file | 保留给调试器中与实现相关的操作;不应该出现在任何类文件中 | ||
impdep2 | 0xff | reserved for implementation-dependent operations within debuggers; should not appear in any class file | 保留给调试器中与实现相关的操作;不应该出现在任何类文件中 |
实践出真理:
TT .java文件:
public class TT {
public static void main (String[] args){
int i=1;
long l=1L;
float f=2.0f;
double d=2.0;
byte b=123;
boolean bo=false;
short s=23;
char c='q';
Integer in = new Integer(1);
String str = "fdafas";
System.out.println(str+f);
}
}
编译为TT.class后使用javap -c TT.class进行反编译(我使用的jdk是1.8):
Compiled from "TT.java"
public class TT {
public TT();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1//将int型1存入栈中;
1: istore_1//将栈顶int型值存入本地第一个变量中
//int i = 1;
2: lconst_1//将long型1存入栈中
3: lstore_2//将栈顶long型值存入本地第二个变量中
//long l = 1;
4: fconst_2
5: fstore 4 //将栈顶float值存入index为4的变量中
//float f = 2.0f;
7: ldc2_w #2//将常量池中index为2的常量存入栈顶// double 2.0d
10: dstore 5//将double值存入第五个变量中
//double b = 2.0;
12: bipush 123//将byte型123当做一个int值存入栈中
14: istore 7//将栈顶的int值存入index为7的变量中
//byte b=123;
16: iconst_0//将int型0存入栈中
17: istore 8
//boolean bo=false; //boolean 在内存中为0(false)和1(true)
19: bipush 23//将byte型23当做一个int值存入栈中
21: istore 9//将栈顶的int值存入index为9的变量中
//short s=23;
23: bipush 113
25: istore 10
//char c='q';
27: new #4//创建一个类常量池中index为4的引用型值并存入栈中// class java/lang/Integer
// new Integer();
30: dup//复制栈顶数值
31: iconst_1//将int型1存入栈中;
32: invokespecial #5//调用在常量池中被标识为5的实例方法// Method java/lang/Integer."<init>":(I)V
35: astore 11//将栈顶引用型变量存入index为11的变量中
//Integer in = new Integer(1);
37: ldc #6//将常量池中index为6的常量存入栈中// String fdafas
39: astore 12
//String str = "fdafas";
41: getstatic #7//调用在常量池中被标记为7的类静态字段// Field java/lang/System.out:Ljava/io/PrintStream;
44: new #8//创建一个类常量池中index为8的引用型值并存入栈中// class java/lang/StringBuilder
47: dup//复制栈顶数值
48: invokespecial #9//调用在常量池中被标识为9的实例方法// Method java/lang/StringBuilder."<init>":()V
//new StringBuilder()
51: aload 12//将index为12的引用型值加载到栈中
53: invokevirtual #10//调用常量池中index为10的实例虚拟方法// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
//StringBuilder.append(str);
56: fload 4//加载index为4的float型数值到栈中
58: invokevirtual #11//调用常量池中index为11的实例虚拟方法// Method java/lang/StringBuilder.append:(F)Ljava/lang/StringBuilder;
//StringBuilder.append(f)
61: invokevirtual #12//调用常量池中index为12的实例虚拟方法// // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
//StringBuilder.toString()
64: invokevirtual #13 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
//PrintStream.println(string)
67: return
}