public class Demo3_9 {
public Demo3_9() { }
private void test1() { }
private final void test2() { }
public void test3() { }
public static void test4() { }
public static void main(String[] args) {
Demo3_9 d = new Demo3_9();
d.test1();// private方法
d.test2();// final方法
d.test3();// public方法
d.test4();// static方法
Demo3_9.test4();
}
}
Oracle 提供的 javap 工具来反编译 class 文件,上面程序对应的字节码
方法调用字节码分析:
执行第0条指令new:首先会为要创建的对象再堆空间的伊甸园分配空间,分配完将对象的引用d压入操作数栈
执行第3条指令dup:将栈顶元素(即对象的引用d)复制一份,因为后续调用完构造方法会将栈顶元素出栈,如果不复制d,调用完构造方法,引用d会被出栈,后面的astore_1就没有东西可以存储到局部变量表了。
执行第4条指令invokespecial:调用构造方法,并将栈顶的引用d的复制出栈
执行第7条指令astore_1:将操作数栈中的引用d放到局部变量表中对应的槽位上
执行第8条指令aload_1:将局部变量表中的引用d加载到操作数栈中
执行第9条指令invokespecial:调用普通方法,并将栈顶元素出栈
。。。
执行第20条指令aload_1:将局部变量表中的引用d加载到操作数栈中
执行第21条指令pop:将操作数栈中的引用d出栈
执行第22条指令invokestatic:调用静态方法
tips:
调用静态构造方法,不需要通过对象来调用,所以第20、21条指令是没有意义的,对象的引用d进操作数栈之后就被pop出来了,调用静态构造方法不需要对象的引用d,所以调用静态方法时建议用类来调用而不是对象。