二进制字节码主要包含3个重要的信息:
类基本信息
常量池
类的方法定义(包含了虚拟机指令)
首先我们可以先编写一个简单的java文件
public class JvmDemo {
public static void main(String[] args) {
System.out.println("hello world");
}
}
打开命令窗口指向class文件目录下输入命令>javap -v JvmDemo.class
就会显示反编译后的详细信息:
Classfile /D:/workspace/day01easyjdbc01/target/classes/com/demo/jvm/JvmDemo.class
Last modified 2020-3-29; size 550 bytes
MD5 checksum ea533ef210bb0cb59171c10750cd6587
Compiled from "JvmDemo.java"
public class com.demo.jvm.JvmDemo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool: //运行时常量池
#1 = Methodref #6.#20 // java/lang/Object."<init>":()V
#2 = Fieldref #21.#22 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #23 // hello world
#4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #26 // com/demo/jvm/JvmDemo
#6 = Class #27 // java/lang/Object
.....
{ //类的方法定义
public com.demo.jvm.JvmDemo(); //默认构造函数
descriptor: ()V
flags: ACC_PUBLIC
Code:
....
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//最大栈深度为2,局部变量个数是1
//下面的0 3 5 8数字代表虚拟机指令,而执行引擎里面的解释器翻译的是数字后面的语句
例如虚拟机读取到指令0,解释器就通过getstatic #2 翻译 找到常量池里面的#2以此查找
0: getstatic (表示获取静态变量) #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc (加载) #3 // String hello world
5: invokevirtual(执行虚方法调用) #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return (方法执行结束)
}