举例来说。
public class Writer {private String name;
static String mark = "作者";
public static void main(String[] args) {
print(mark);
Writer w = new Writer();
print(w.name);
}
public static void print(String arg) {
System.out.println(arg);
}
}
通过 jclasslib 看一下 main() 方法的字节码指令。
getstatic #2 ,访问静态变量 mark
getfield #6 ,访问成员变量 name
05、方法调用和返回指令方法调用指令有 5 个,分别用于不同的场景:
invokevirtual:用于调用对象的成员方法,根据对象的实际类型进行分派,支持多态。
invokeinterface:用于调用接口方法,会在运行时搜索由特定对象实现的接口方法进行调用。
invokespecial:用于调用一些需要特殊处理的方法,包括构造方法、私有方法和父类方法。
invokestatic:用于调用静态方法。
invokedynamic:用于在运行时动态解析出调用点限定符所引用的方法,并执行。
举例来说。
public class InvokeExamples {private void run() {
List ls = new ArrayList();
ls.add("难顶");
ArrayList als = new ArrayList();
als.add("学不动了");
}
public static void print() {
System.out.println("invokestatic");
}
public static void main(String[] args) {
print();
InvokeExamples invoke = new InvokeExamples();
invoke.run();
}
}
我们用 javap -c InvokeExamples.class 来反编译一下。
Compiled from "InvokeExamples.java"public class com.itwanger.jvm.InvokeExamples {
public com.itwanger.jvm.InvokeExamples();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
private void run();
Code:
0: new #2 // class java/util/ArrayList
3: dup
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #4 // String 难顶
11: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: new #2 // class java/util/ArrayList
20: dup
21: invokespecial #3 // Method java/util/ArrayList."<init>":()V
24: astore_2
25: aload_2
26: ldc #6 // String 学不动了
28: invokevirtual #7 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
31: pop
32: return
public static void print();
Code:
0: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #9 // String invokestatic
5: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #11 // Method print:()V
3: new #12 // class com/itwanger/jvm/InvokeExamples
6: dup
7: invokespecial #13 // Method "<init>":()V
10: astore_1
11: aload_1
12: invokevirtual #14 // Method run:()V
15: return
}
InvokeExamples 类有 4 个方法,包括缺省的构造方法在内。
1)InvokeExamples() 构造方法中
缺省的构造方法内部会调用超类 Object 的初始化构造方法:
`invokespecial #1 // Method java/lang/Object."<init>":()V`2)成员方法 run() 中
invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z