JVM method dispatch:修订间差异

来自WHY42
Riguz留言 | 贡献
Riguz留言 | 贡献
Riguz移动页面JVM:Method DispatchJVM method dispatch,不留重定向
 
(未显示同一用户的8个中间版本)
第11行: 第11行:
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">
|+ 說明文字
|-
| <syntaxhighlight lang="java">
public class Hello {
public class Hello {
     public static void sayHello(String msg) {
     public static void sayHello(String msg) {
第24行: 第21行:
     }
     }
}
}
</syntaxhighlight> || 👉 ||
</syntaxhighlight>
 
compiled:
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
    // Riguz!
// Riguz!
    #4 = String            #23
#4 = String            #23
    // com/riguz/Hello.sayHello:(Ljava/lang/String;)V
// com/riguz/Hello.sayHello:(Ljava/lang/String;)V
    #5 = Methodref          #6.#24  
#5 = Methodref          #6.#24  
...
...
   public static void main(java.lang.String[]);
   public static void main(java.lang.String[]);
第44行: 第43行:
}
}
</syntaxhighlight>
</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

invokedynamic