JVM method dispatch:修订间差异
小 Riguz移动页面JVM:Method Dispatch至JVM method dispatch,不留重定向 |
|||
(未显示同一用户的9个中间版本) | |||
第10行: | 第10行: | ||
invoke a static method, the method is from the constant pool by <syntaxhighlight lang="java">index= (indexbyte1 << 8) | indexbyte2</syntaxhighlight> | invoke a static method, the method is from the constant pool by <syntaxhighlight lang="java">index= (indexbyte1 << 8) | indexbyte2</syntaxhighlight> | ||
<syntaxhighlight lang="java"> | |||
public class Hello { | |||
public static void sayHello(String msg) { | |||
System.out.println(msg); | |||
} | |||
public static void main(String[] args) { | |||
sayHello("Riguz!"); | |||
} | |||
} | |||
</syntaxhighlight> | |||
compiled: | |||
<syntaxhighlight lang="java"> | |||
// Riguz! | |||
#4 = String #23 | |||
// com/riguz/Hello.sayHello:(Ljava/lang/String;)V | |||
#5 = Methodref #6.#24 | |||
... | |||
public static void main(java.lang.String[]); | |||
descriptor: ([Ljava/lang/String;)V | |||
flags: ACC_PUBLIC, ACC_STATIC | |||
Code: | |||
stack=1, locals=1, args_size=1 | |||
0: ldc #4 | |||
2: invokestatic #5 | |||
5: return | |||
LineNumberTable: | |||
line 9: 0 | |||
line 10: 5 | |||
} | |||
</syntaxhighlight> | |||
== invokevirtual == | == invokevirtual == | ||
Invoke instance method; dispatch based on class | |||
<syntaxhighlight lang="java"> | |||
invokevirtual | |||
indexbyte1 | |||
indexbyte2 | |||
</syntaxhighlight> | |||
Operand stack: | |||
<pre> | |||
..., objectref, [arg1, [arg2 ...]] → | |||
</pre> | |||
<syntaxhighlight lang="java"> | |||
// java/lang/System.out:Ljava/io/PrintStream; | |||
#2 = Fieldref #19.#20 | |||
// java/io/PrintStream.println:(Ljava/lang/String;)V | |||
#3 = Methodref #21.#22 | |||
... | |||
public static void sayHello(java.lang.String); | |||
descriptor: (Ljava/lang/String;)V | |||
flags: ACC_PUBLIC, ACC_STATIC | |||
Code: | |||
stack=2, locals=1, args_size=1 | |||
0: getstatic #2 | |||
3: aload_0 | |||
4: invokevirtual #3 | |||
7: return | |||
</syntaxhighlight> | |||
== invokespecial == | == invokespecial == | ||
Invoke instance method; special handling for superclass, private, and instance initialization method invocations | |||
The difference between the invokespecial instruction and the invokevirtual instruction is that invokevirtual invokes a method based on the class of the object. The invokespecial instruction is used to invoke instance initialization methods as well as private methods and methods of a superclass of the current class. | |||
<syntaxhighlight lang="java"> | |||
public HelloWorld(); | |||
descriptor: ()V | |||
flags: (0x0001) 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 | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="java"> | |||
public static HelloWorld create() { | |||
HelloWorld h = new HelloWorld(); | |||
return h; | |||
} | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="java"> | |||
public static HelloWorld create(); | |||
descriptor: ()LHelloWorld; | |||
flags: (0x0009) ACC_PUBLIC, ACC_STATIC | |||
Code: | |||
stack=2, locals=1, args_size=0 | |||
0: new #2 // class HelloWorld | |||
3: dup | |||
4: invokespecial #3 // Method "<init>":()V | |||
7: astore_0 | |||
8: aload_0 | |||
9: areturn | |||
LineNumberTable: | |||
line 3: 0 | |||
line 4: 8 | |||
</syntaxhighlight> | |||
== invokeinterface == | == invokeinterface == | ||
<syntaxhighlight lang="java"> | |||
public static void main(String[] args) { | |||
SayHello s = new HelloWorld(); | |||
s.hi(); | |||
} | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="java"> | |||
public static void main(java.lang.String[]); | |||
descriptor: ([Ljava/lang/String;)V | |||
flags: (0x0009) ACC_PUBLIC, ACC_STATIC | |||
Code: | |||
stack=2, locals=2, args_size=1 | |||
0: new #5 // class HelloWorld | |||
3: dup | |||
4: invokespecial #6 // Method "<init>":()V | |||
7: astore_1 | |||
8: aload_1 | |||
9: invokeinterface #7, 1 // InterfaceMethod SayHello.hi:()V | |||
14: return | |||
</syntaxhighlight> | |||
== invokedynamic == | == invokedynamic == | ||
2023年12月19日 (二) 06:58的最新版本
Method invocation
invokestatic
invoke a static method:
invokestatic
indexbyte1
indexbyte2
invoke a static method, the method is from the constant pool by
index= (indexbyte1 << 8) | indexbyte2
public class Hello {
public static void sayHello(String msg) {
System.out.println(msg);
}
public static void main(String[] args) {
sayHello("Riguz!");
}
}
compiled:
// Riguz!
#4 = String #23
// com/riguz/Hello.sayHello:(Ljava/lang/String;)V
#5 = Methodref #6.#24
...
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: ldc #4
2: invokestatic #5
5: return
LineNumberTable:
line 9: 0
line 10: 5
}
invokevirtual
Invoke instance method; dispatch based on class
invokevirtual
indexbyte1
indexbyte2
Operand stack:
..., objectref, [arg1, [arg2 ...]] →
// java/lang/System.out:Ljava/io/PrintStream;
#2 = Fieldref #19.#20
// java/io/PrintStream.println:(Ljava/lang/String;)V
#3 = Methodref #21.#22
...
public static void sayHello(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2
3: aload_0
4: invokevirtual #3
7: return
invokespecial
Invoke instance method; special handling for superclass, private, and instance initialization method invocations
The difference between the invokespecial instruction and the invokevirtual instruction is that invokevirtual invokes a method based on the class of the object. The invokespecial instruction is used to invoke instance initialization methods as well as private methods and methods of a superclass of the current class.
public HelloWorld();
descriptor: ()V
flags: (0x0001) 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
public static HelloWorld create() {
HelloWorld h = new HelloWorld();
return h;
}
public static HelloWorld create();
descriptor: ()LHelloWorld;
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=0
0: new #2 // class HelloWorld
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_0
8: aload_0
9: areturn
LineNumberTable:
line 3: 0
line 4: 8
invokeinterface
public static void main(String[] args) {
SayHello s = new HelloWorld();
s.hi();
}
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #5 // class HelloWorld
3: dup
4: invokespecial #6 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokeinterface #7, 1 // InterfaceMethod SayHello.hi:()V
14: return