一、Java代码编译执行
1.1 示意图
+---------------+ +---------------+ +---------------+
| .java |---------->| JAVA Compiler |---------->| .class |-------+
| | | (javac) | | | |
+---------------+ +---------------+ +---------------+ |
|
|
+-----------------------------------------------------------------------+ |
| JVM | |
| +----------+ +---------------+ +---------+ +---------+ | |
| | OS | | JAVA Runtime | | ByteCode| | Class | | |
| | (Linux) |<----| System |<----| Verifier|<----| Loader | |<------+
| +----------+ +---------------+ +---------+ +---------+ |
| |
+-----------------------------------------------------------------------+
1.2 字节码查看
-
用UE或者其它16进制工具(winhex)或者Linux命令
xxd
打开字节码文件,如下图所示:其中
(1)CA FE BA BE
为魔数。魔数值固定不变,且放在文件开头,JVM可以根据文件的开头来判断这个文件是否可能是一个.class文件,如果是,才会继续进行之后的操作。
(2)次版本号(minor version):0
(3)主版本号(major version):61 (16* 3 + 13 = 61),意味着编译该文件的Java版本号为17
-
字节码查看命令:
javap -c 类名
或者javap -v 类名
来反汇编字节码文件
D:\>javap -v ByteCode.class
Classfile /D:/ByteCode.class
Last modified 2024-12-12; size 513 bytes
MD5 checksum 9e3103bd209e0d6546d6f7c99075e5f9
Compiled from "ByteCode.java"
public class ByteCode
minor version: 0
major version: 61
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
#2 = Class #4 // java/lang/Object
#3 = NameAndType #5:#6 // "<init>":()V
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Fieldref #8.#9 // java/lang/System.out:Ljava/io/PrintStream;
#8 = Class #10 // java/lang/System
#9 = NameAndType #11:#12 // out:Ljava/io/PrintStream;
#10 = Utf8 java/lang/System
#11 = Utf8 out
#12 = Utf8 Ljava/io/PrintStream;
#13 = String #14 // ByteCode
#14 = Utf8 ByteCode
#15 = Methodref #16.#17 // java/io/PrintStream.println:(Ljava/lang/String;)V
#16 = Class #18 // java/io/PrintStream
#17 = NameAndType #19:#20 // println:(Ljava/lang/String;)V
#18 = Utf8 java/io/PrintStream
#19 = Utf8 println
#20 = Utf8 (Ljava/lang/String;)V
#21 = Class #14 // ByteCode
#22 = Utf8 Code
#23 = Utf8 LineNumberTable
#24 = Utf8 LocalVariableTable
#25 = Utf8 this
#26 = Utf8 LByteCode;
#27 = Utf8 main
#28 = Utf8 ([Ljava/lang/String;)V
#29 = Utf8 args
#30 = Utf8 [Ljava/lang/String;
#31 = Utf8 SourceFile
#32 = Utf8 ByteCode.java
{
public ByteCode();
descriptor: ()V
flags: 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
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LByteCode;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #13 // String ByteCode
5: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 3: 0
line 4: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
}
SourceFile: "ByteCode.java"
- JDK version和class file version(Class编译版本号)对应关系
JDK 19 = 63,
JDK 18 = 62,
JDK 17 = 61,
JDK 16 = 60,
JDK 15 = 59,
JDK 14 = 58,
JDK 13 = 57,
JDK 12 = 56,
JDK 11 = 55,
JDK 10 = 54,
JDK 9 = 53,
JDK 8 = 52,
JDK 7 = 51,
JDK 6.0 = 50,
JDK 5.0 = 49,
JDK 1.4 = 48,
JDK 1.3 = 47,
JDK 1.2 = 46,
JDK 1.1 = 45.0-45.6