javap定义
javap是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。用于分解class文件。
测试类
public class JavapTest {
private static final int _P_1 = 1;
public static final int _P_2 = 2;
public static void main(String[] args) {
int m = 0, n = 0;
for (int i = 0; i < 10; i++) {
m = m++;
n = ++n;
}
System.out.println("m = " + m);
System.out.println("n = " + n);
}
}
javap命令参数
C:\Users\l>javap -help
用法: javap <options> <classes>
其中, 可能的选项包括:
-? -h --help -help 输出此帮助消息
-version 版本信息
-v -verbose 输出附加信息
-l 输出行号和本地变量表
-public 仅显示公共类和成员
-protected 显示受保护的/公共类和成员
-package 显示程序包/受保护的/公共类
和成员 (默认)
-p -private 显示所有类和成员
-c 对代码进行反汇编
-s 输出内部类型签名
-sysinfo 显示正在处理的类的
系统信息 (路径, 大小, 日期, MD5 散列)
-constants 显示最终常量
--module <模块>, -m <模块> 指定包含要反汇编的类的模块
--module-path <路径> 指定查找应用程序模块的位置
--system <jdk> 指定查找系统模块的位置
--class-path <路径> 指定查找用户类文件的位置
-classpath <路径> 指定查找用户类文件的位置
-cp <路径> 指定查找用户类文件的位置
-bootclasspath <路径> 覆盖引导类文件的位置
GNU 样式的选项可使用 = (而非空白) 来分隔选项名称
及其值。
每个类可由其文件名, URL 或其
全限定类名指定。示例:
path/to/MyClass.class
jar:file:///path/to/MyJar.jar!/mypkg/MyClass.class
java.lang.Object
javap -version:显示java版本
11.0.14
javap -p:显示所有类和成员
D:\Source\beike_one\JAVASE_02>javap -p JavapTest.class
Compiled from "JavapTest.java"
public class JavapTest {
private static final int _P_1;
public static final int _P_2;
public JavapTest();
public static void main(java.lang.String[]);
javap -public:仅显示公共类和成员
D:\Source\beike_one\JAVASE_02>javap -public JavapTest.class
Compiled from "JavapTest.java"
public class JavapTest {
public static final int _P_2;
public JavapTest();
public static void main(java.lang.String[]);
}
javap -l:输出行号和本地变量表
D:\Source\beike_one\JAVASE_02>javap -p -l JavapTest.class
Compiled from "JavapTest.java"
public class JavapTest {
private static final int _P_1;
public static final int _P_2;
public JavapTest();
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
LineNumberTable:
line 7: 0
line 8: 4
line 9: 12
line 10: 17
line 8: 22
line 12: 28
line 13: 40
line 14: 52
}
javap -v/-p -v:
这是两个命令:
javap -v JavapTest.class
或者
javap -p -v JavapTest.class
命令说明是:
输出附加信息class文件的路径
最后修改时间
文件大小等类的全路径
源(java)文件等常量池常量定义
值构造方法程序调用及执行逻辑(这个涉及的内容就比较多了)
D:\Source\beike_one\JAVASE_02>javap -p -v JavapTest.class
Classfile /D:/Source/beike_one/JAVASE_02/JavapTest.class
Last modified 2022年3月9日; size 1039 bytes
MD5 checksum fa1231c69dc6eca6a29a533e2f027c0a
Compiled from "JavapTest.java"
public class JavapTest
minor version: 0
major version: 55
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #6 // JavapTest
super_class: #7 // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 3
Constant pool:
#1 = Methodref #7.#23 // java/lang/Object."<init>":()V
#2 = Fieldref #24.#25 // java/lang/System.out:Ljava/io/PrintStream;
#3 = InvokeDynamic #0:#29 // #0:makeConcatWithConstants:(I)Ljava/lang/String;
#4 = Methodref #30.#31 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = InvokeDynamic #1:#29 // #1:makeConcatWithConstants:(I)Ljava/lang/String;
#6 = Class #33 // JavapTest
#7 = Class #34 // java/lang/Object
#8 = Utf8 _P_1
#9 = Utf8 I
#10 = Utf8 ConstantValue
#11 = Integer 1
#12 = Utf8 _P_2
#13 = Integer 2
#14 = Utf8 <init>
#15 = Utf8 ()V
#16 = Utf8 Code
#17 = Utf8 LineNumberTable
#18 = Utf8 main
#19 = Utf8 ([Ljava/lang/String;)V
#20 = Utf8 StackMapTable
#21 = Utf8 SourceFile
#22 = Utf8 JavapTest.java
#23 = NameAndType #14:#15 // "<init>":()V
#24 = Class #35 // java/lang/System
#25 = NameAndType #36:#37 // out:Ljava/io/PrintStream;
#26 = Utf8 BootstrapMethods
#27 = MethodHandle 6:#38 // REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#28 = String #39 // m = \u0001
#29 = NameAndType #40:#41 // makeConcatWithConstants:(I)Ljava/lang/String;
#30 = Class #42 // java/io/PrintStream
#31 = NameAndType #43:#44 // println:(Ljava/lang/String;)V
#32 = String #45 // n = \u0001
#33 = Utf8 JavapTest
#34 = Utf8 java/lang/Object
#35 = Utf8 java/lang/System
#36 = Utf8 out
#37 = Utf8 Ljava/io/PrintStream;
#38 = Methodref #46.#47 // java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#39 = Utf8 m = \u0001
#40 = Utf8 makeConcatWithConstants
#41 = Utf8 (I)Ljava/lang/String;
#42 = Utf8 java/io/PrintStream
#43 = Utf8 println
#44 = Utf8 (Ljava/lang/String;)V
#45 = Utf8 n = \u0001
#46 = Class #48 // java/lang/invoke/StringConcatFactory
#47 = NameAndType #40:#52 // makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#48 = Utf8 java/lang/invoke/StringConcatFactory
#49 = Class #54 // java/lang/invoke/MethodHandles$Lookup
#50 = Utf8 Lookup
#51 = Utf8 InnerClasses
#52 = Utf8 (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#53 = Class #55 // java/lang/invoke/MethodHandles
#54 = Utf8 java/lang/invoke/MethodHandles$Lookup
#55 = Utf8 java/lang/invoke/MethodHandles
{
private static final int _P_1;
descriptor: I
flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
ConstantValue: int 1
public static final int _P_2;
descriptor: I
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: int 2
public JavapTest();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: iconst_0
1: istore_1
2: iconst_0
3: istore_2
4: iconst_0
5: istore_3
6: iload_3
7: bipush 10
9: if_icmpge 28
12: iload_1
13: iinc 1, 1
16: istore_1
17: iinc 2, 1
20: iload_2
21: istore_2
22: iinc 3, 1
25: goto 6
28: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
31: iload_1
32: invokedynamic #3, 0 // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
37: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
43: iload_2
44: invokedynamic #5, 0 // InvokeDynamic #1:makeConcatWithConstants:(I)Ljava/lang/String;
49: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
52: return
LineNumberTable:
line 7: 0
line 8: 4
line 9: 12
line 10: 17
line 8: 22
line 12: 28
line 13: 40
line 14: 52
StackMapTable: number_of_entries = 2
frame_type = 254 /* append */
offset_delta = 6
locals = [ int, int, int ]
frame_type = 250 /* chop */
offset_delta = 21
}
SourceFile: "JavapTest.java"
InnerClasses:
public static final #50= #49 of #53; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
0: #27 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#28 m = \u0001
1: #27 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#32 n = \u0001
javap -c:对代码进行反汇编
javap-c输出内部javap-v中已经有了,我们详细介绍下javap-c命令的输出内容0:iconst_0前面0:表示执行的顺序,iconst_0把值0放入栈顶,_0中的0代表压栈的值,如:iconst_5,即把5压入栈顶1:istore_1将栈顶的值放入变量1中,_1代表变量的序列,本例中为:m,如:istore_2即为变量n赋值6:iload_3将变量3即i的的值放入栈顶,与iconst不同的是,iload操作的值是已经定义好存在的值,iconst是定义时的压栈操作13:iinc1,1将变量1的值加1
D:\Source\beike_one\JAVASE_02>javap -c JavapTest.class
Compiled from "JavapTest.java"
public class JavapTest {
public static final int _P_2;
public JavapTest();
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_0
1: istore_1
2: iconst_0
3: istore_2
4: iconst_0
5: istore_3
6: iload_3
7: bipush 10
9: if_icmpge 28
12: iload_1
13: iinc 1, 1
16: istore_1
17: iinc 2, 1
20: iload_2
21: istore_2
22: iinc 3, 1
25: goto 6
28: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
31: iload_1
32: invokedynamic #3, 0 // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
37: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
43: iload_2
44: invokedynamic #5, 0 // InvokeDynamic #1:makeConcatWithConstants:(I)Ljava/lang/String;
49: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
52: return
}