基本的HelloWorld类:
public class HelloWorld{
public static void main(String [] args){
System.out.println("Hello World");
}
}
C:\demo>javap -verbose HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object
SourceFile: "HelloWorld.java"
minor version: 0
major version: 50
Constant pool:
//常量池,里面的内容很重要。
//Method:方法
//Field:字段
//String:字符串
//Asciz:方法签名 <init>由jvm调用,其他是不能够去调用它的。
//NameAndType:变量名的类型
//Class:类
//我们看看invokespecial #1 这条语句
//#1是对应的一个方法(Method).
//其中右边 #6.#15 表示从常量池的#6(表示偏移量)跳到进入#15去。
//#6对应的是class 到#15对应的是 NameAndType:#7:#8。
//在看#7对应的是:Asciz <init> ,#8对应的是()V 表示没有返回值(void),()表示方法没//有参数。所以invokespecial #1指的是:调用一个Method java/lang/Object."<init>":()V
//常见JVM指令:
//invokespecial:表示调用超类构造方法,实例初始化方法,私有方法。
//invokevirtual:调用实例方法
//invokestatic:调用静态方法
//invokeinterface:调用接口方法
//new:创建一个对象,并将其引用值压入栈顶
const #1 = Method #6.#15; // java/lang/Object."<init>":()V
const #2 = Field #16.#17; // java/lang/System.out:Ljava/io/Print
const #3 = String #18; // Hello World
const #4 = Method #19.#20; // java/io/PrintStream.println:(Ljava/V
const #5 = class #21; // HelloWorld
const #6 = class #22; // java/lang/Object
const #7 = Asciz <init>;
const #8 = Asciz ()V;
const #9 = Asciz Code;
const #10 = Asciz LineNumberTable;
const #11 = Asciz main;
const #12 = Asciz ([Ljava/lang/String;)V;
const #13 = Asciz SourceFile;
const #14 = Asciz HelloWorld.java;
const #15 = NameAndType #7:#8;// "<init>":()V
const #16 = class #23; // java/lang/System
const #17 = NameAndType #24:#25;// out:Ljava/io/PrintStream;
const #18 = Asciz Hello World;
const #19 = class #26; // java/io/PrintStream
const #20 = NameAndType #27:#28;// println:(Ljava/lang/String;)V
const #21 = Asciz HelloWorld;
const #22 = Asciz java/lang/Object;
const #23 = Asciz java/lang/System;
const #24 = Asciz out;
const #25 = Asciz Ljava/io/PrintStream;;
const #26 = Asciz java/io/PrintStream;
const #27 = Asciz println;
const #28 = Asciz (Ljava/lang/String;)V;
public HelloWorld();
//默认构造函数
//Locals表示方法内局部变量个数,该例中是1,有些人疑惑的是HelloWorld()中明明没有参数啊,应该是0。
//当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用
//非static方法,在调用的时候都会给方法默认加上一个当前对象(this)类型的参数,不需要在方法中定义,
//这个时候局部变量列表中index为0的位置保存的是this,其他索引号按变量定义顺序累加
//static方法不依赖对象,所以不用传this
//Args_size表示参数个数,public HelloWorld();会传一个this进去,所以value是1
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[]);
Code:
Stack=2, Locals=1, Args_size=1
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/St
8: return
LineNumberTable:
line 3: 0
line 4: 8
}
如果加上下面的代码:
public static void print(){
System.out.println("Hello World");
}
会得到下面的指令代码:
public static void print();
Code:
Stack=2, Locals=0, Args_size=0
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
LineNumberTable:
line 3: 0
line 4: 8
Locals=0, Args_size=0