Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javac实现:方法调用产生什么jvm指令?_Java_Jvm_Javac_Method Call - Fatal编程技术网

Javac实现:方法调用产生什么jvm指令?

Javac实现:方法调用产生什么jvm指令?,java,jvm,javac,method-call,Java,Jvm,Javac,Method Call,假设我在java中有一个方法调用站点。等效的jvm字节码是什么(除了转换为invokevirtual/static e.t.c的调用)?我更感兴趣的是在堆栈上加载接收器的命令 -显然,一个命令是aload -另一种可能是另一个调用返回堆栈上的重新对象 -第三,新指令。(例如新的A().foo()。它会被复制。但是复制的内容会被构造函数使用) -四个,也许(??)Dup。(如果有a.foo();a.bar();编译器是否有可能生成aload然后生成dup而不是aload aload?) 我最大的问

假设我在java中有一个方法调用站点。等效的jvm字节码是什么(除了转换为invokevirtual/static e.t.c的调用)?我更感兴趣的是在堆栈上加载接收器的命令

-显然,一个命令是aload

-另一种可能是另一个调用返回堆栈上的重新对象

-第三,新指令。(例如新的A().foo()。它会被复制。但是复制的内容会被构造函数使用)

-四个,也许(??)Dup。(如果有a.foo();a.bar();编译器是否有可能生成aload然后生成dup而不是aload aload?)

我最大的问题是剩余的dup命令。因为他们会洗牌。javac什么时候生产它们?它在编译呼叫站点时是否使用它们

我一直在努力寻找没有运气的纪录片。然后找到了源代码,但要深入研究还需要几天时间。我相信这些文件负责翻译/编译过程。

几乎任何产生引用的字节码指令都可以被javac用来加载接收器

  • aload、invokeX、new+dup
    你刚才提到的那些
  • getfield,getstatic

    field.method();
    
    MyClass.class.getName();
    
  • aaload

    arr[index].method();
    
  • anewarray

    (new Object[0]).hashCode();
    
    (new byte[5][10]).getClass();
    
  • multianewarray

    (new Object[0]).hashCode();
    
    (new byte[5][10]).getClass();
    
  • checkcast

    ((List) obj).size();
    
  • ldc

    field.method();
    
    MyClass.class.getName();
    
  • acost\u null

    ((Object) null).getClass();
    
  • dup

    IntSupplier s = field::hashCode;
    
    这里的
    dup
    +
    invokevirtual
    用于发出一个复杂的空检查:

    getstatic     #2      // Field field:Ljava/lang/String;
    dup
    invokevirtual #3      // Method java/lang/Object.getClass:()Ljava/lang/Class;
    pop
    invokedynamic #4,  0  // InvokeDynamic #0:getAsInt
    

您可以使用javap命令查看类中使用的jvm字节码——是的,但它不能涵盖所有可能性。我不能确定我的示例是否涵盖了您自己注意到的所有内容,
javac
使用
dup
进行构造函数调用。通常,在解引用同一变量时,它不使用
dup
。变量访问总是被编译成变量访问。但反过来说,它可能会添加源代码中没有出现的合成变量。堆栈操作相当罕见。但是一个例子是
objArray[index]+=“string”
,它使用
dup2
(在JDK11中)克隆数组引用和索引,因为更新需要
aaload
aastore
。另一个场景是
(变量=表达式).method()
;请注意,从JDK 9开始,编译器将插入一个
Objects.requirennoull(…)
调用,而不是
….getClass()
以进行内部
null
检查(另请参阅)