解析字节码的作用
- 通过反编译生成字节码文件,可以深入了解Java工作机制,但自己分析类文件结构太麻烦,除了第三方的jclasslib工具外,官方提供了javap
- javap是jdk自带的反解析工具,它的作用是根据class字节码文件,反解析出当前类对应的code区(字节码指令)、局部变量表、异常表、代码行偏移量映射表、常量池等信息
- 通过局部变量表,可以查看局部变量的作用域范围、所在槽位等信息,甚至可以看到槽位复用信息
java -g操作
- 解析字节码文件得到的信息中,有些信息(如局部变量表、指令和代码行偏移量映射表、常量池中方法的参数名称等)需要在使用javac编译成class文件时,指定参数才能输出
- 直接使用javac xx.java,不会生成对应局部变量表等信息,使用javac -g xx.java可以生成相关信息,如使用eclipse或IDEA,默认情况下,在编译时会帮你生成局部变量表,指令和代码偏移量映射表等信息
javap
- classes是要反编译的class文件
- 在命令行直接输入javap或javap -help可以看到javap的options有如下选项
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -version JavapTest.class
1.8.0_131
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
int getNum(int);
protected char showGender();
public void showInfo();
static {};
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -public JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
public void showInfo();
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -protected JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
protected char showGender();
public void showInfo();
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -private JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
private int num;
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
private com.chapter09.JavapTest(boolean);
private void methodPrivate();
int getNum(int);
protected char showGender();
public void showInfo();
static {};
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -package JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
int getNum(int);
protected char showGender();
public void showInfo();
static {};
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -sysinfo JavapTest.class
Classfile /C:/Users/Administrator/IdeaProjects/jvm/target/classes/com/chapter09/JavapTest.class
Last modified 2024-5-27; size 1348 bytes
MD5 checksum 85dc41e7e2e7128d8899b5d131d7975f
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
int getNum(int);
protected char showGender();
public void showInfo();
static {};
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -constants JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS = 1;
public com.chapter09.JavapTest();
int getNum(int);
protected char showGender();
public void showInfo();
static {};
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -s JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
descriptor: Z
protected char gender;
descriptor: C
public java.lang.String info;
descriptor: Ljava/lang/String;
public static final int COUNTS;
descriptor: I
public com.chapter09.JavapTest();
descriptor: ()V
int getNum(int);
descriptor: (I)I
protected char showGender();
descriptor: ()C
public void showInfo();
descriptor: ()V
static {};
descriptor: ()V
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -l JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
LineNumberTable:
line 20: 0
line 18: 4
line 20: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this Lcom/chapter09/JavapTest;
int getNum(int);
LineNumberTable:
line 26: 0
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcom/chapter09/JavapTest;
0 7 1 i I
protected char showGender();
LineNumberTable:
line 29: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/chapter09/JavapTest;
public void showInfo();
LineNumberTable:
line 32: 0
line 33: 3
line 34: 30
LocalVariableTable:
Start Length Slot Name Signature
0 31 0 this Lcom/chapter09/JavapTest;
3 28 1 i I
static {};
LineNumberTable:
line 15: 0
line 16: 3
LocalVariableTable:
Start Length Slot Name Signature
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -l JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
LineNumberTable:
line 20: 0
line 18: 4
line 20: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this Lcom/chapter09/JavapTest;
int getNum(int);
LineNumberTable:
line 26: 0
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcom/chapter09/JavapTest;
0 7 1 i I
protected char showGender();
LineNumberTable:
line 29: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/chapter09/JavapTest;
public void showInfo();
LineNumberTable:
line 32: 0
line 33: 3
line 34: 30
LocalVariableTable:
Start Length Slot Name Signature
0 31 0 this Lcom/chapter09/JavapTest;
3 28 1 i I
static {};
LineNumberTable:
line 15: 0
line 16: 3
LocalVariableTable:
Start Length Slot Name Signature
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -c JavapTest.class
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest {
boolean flag;
protected char gender;
public java.lang.String info;
public static final int COUNTS;
public com.chapter09.JavapTest();
Code:
0: aload_0
1: invokespecial #1
4: aload_0
5: ldc #2
7: putfield #3
10: return
int getNum(int);
Code:
0: aload_0
1: getfield #5
4: iload_1
5: iadd
6: ireturn
protected char showGender();
Code:
0: aload_0
1: getfield #6
4: ireturn
public void showInfo();
Code:
0: bipush 10
2: istore_1
3: getstatic #7
6: new #8
9: dup
10: invokespecial #9
13: aload_0
14: getfield #3
17: invokevirtual #10
20: iload_1
21: invokevirtual #11
24: invokevirtual #12
27: invokevirtual #13
30: return
static {};
Code:
0: ldc #14
2: astore_0
3: return
}
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter09>javap -v JavapTest.class
Classfile /C:/Users/Administrator/IdeaProjects/jvm/target/classes/com/chapter09/JavapTest.class
Last modified 2024-5-27; size 1348 bytes
MD5 checksum 85dc41e7e2e7128d8899b5d131d7975f
Compiled from "JavapTest.java"
public class com.chapter09.JavapTest
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #16.#46
#2 = String #47
#3 = Fieldref #15.#48
#4 = Fieldref #15.#49
#5 = Fieldref #15.#50
#6 = Fieldref #15.#51
#7 = Fieldref #52.#53
#8 = Class #54
#9 = Methodref #8.#46
#10 = Methodref #8.#55
#11 = Methodref #8.#56
#12 = Methodref #8.#57
#13 = Methodref #58.#59
#14 = String #60
#15 = Class #61
#16 = Class #62
#17 = Utf8 num
#18 = Utf8 I
#19 = Utf8 flag
#20 = Utf8 Z
#21 = Utf8 gender
#22 = Utf8 C
#23 = Utf8 info
#24 = Utf8 Ljava/lang/String;
#25 = Utf8 COUNTS
#26 = Utf8 ConstantValue
#27 = Integer 1
#28 = Utf8 <init>
#29 = Utf8 ()V
#30 = Utf8 Code
#31 = Utf8 LineNumberTable
#32 = Utf8 LocalVariableTable
#33 = Utf8 this
#34 = Utf8 Lcom/chapter09/JavapTest;
#35 = Utf8 (Z)V
#36 = Utf8 methodPrivate
#37 = Utf8 getNum
#38 = Utf8 (I)I
#39 = Utf8 i
#40 = Utf8 showGender
#41 = Utf8 ()C
#42 = Utf8 showInfo
#43 = Utf8 <clinit>
#44 = Utf8 SourceFile
#45 = Utf8 JavapTest.java
#46 = NameAndType #28:#29
#47 = Utf8 java
#48 = NameAndType #23:#24
#49 = NameAndType #19:#20
#50 = NameAndType #17:#18
#51 = NameAndType #21:#22
#52 = Class #63
#53 = NameAndType #64:#65
#54 = Utf8 java/lang/StringBuilder
#55 = NameAndType #66:#67
#56 = NameAndType #66:#68
#57 = NameAndType #69:#70
#58 = Class #71
#59 = NameAndType #72:#73
#60 = Utf8 www.lotus.com
#61 = Utf8 com/chapter09/JavapTest
#62 = Utf8 java/lang/Object
#63 = Utf8 java/lang/System
#64 = Utf8 out
#65 = Utf8 Ljava/io/PrintStream;
#66 = Utf8 append
#67 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#68 = Utf8 (I)Ljava/lang/StringBuilder;
#69 = Utf8 toString
#70 = Utf8 ()Ljava/lang/String;
#71 = Utf8 java/io/PrintStream
#72 = Utf8 println
#73 = Utf8 (Ljava/lang/String;)V
{
boolean flag;
descriptor: Z
flags:
protected char gender;
descriptor: C
flags: ACC_PROTECTED
public java.lang.String info;
descriptor: Ljava/lang/String;
flags: ACC_PUBLIC
public static final int COUNTS;
descriptor: I
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: int 1
public com.chapter09.JavapTest();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1
4: aload_0
5: ldc #2
7: putfield #3
10: return
LineNumberTable:
line 20: 0
line 18: 4
line 20: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this Lcom/chapter09/JavapTest;
int getNum(int);
descriptor: (I)I
flags:
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: getfield #5
4: iload_1
5: iadd
6: ireturn
LineNumberTable:
line 26: 0
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcom/chapter09/JavapTest;
0 7 1 i I
protected char showGender();
descriptor: ()C
flags: ACC_PROTECTED
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #6
4: ireturn
LineNumberTable:
line 29: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/chapter09/JavapTest;
public void showInfo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=1
0: bipush 10
2: istore_1
3: getstatic #7
6: new #8
9: dup
10: invokespecial #9
13: aload_0
14: getfield #3
17: invokevirtual #10
20: iload_1
21: invokevirtual #11
24: invokevirtual #12
27: invokevirtual #13
30: return
LineNumberTable:
line 32: 0
line 33: 3
line 34: 30
LocalVariableTable:
Start Length Slot Name Signature
0 31 0 this Lcom/chapter09/JavapTest;
3 28 1 i I
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=1, args_size=0
0: ldc #14
2: astore_0
3: return
LineNumberTable:
line 15: 0
line 16: 3
LocalVariableTable:
Start Length Slot Name Signature
}
SourceFile: "JavapTest.java"