首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java字节码、java供应商和invokedynamic参数

Java字节码、java供应商和invokedynamic参数
EN

Stack Overflow用户
提问于 2016-07-28 17:48:14
回答 1查看 170关注 0票数 4

我有这个类,我编译它。

代码语言:javascript
复制
package org.test;

import java.util.function.Supplier;

public class Test {
    static String get() { return "!!"; }

    public static void main(String[] args) {
        Supplier<String> sup = Test::get;
        System.out.println(sup.get());
    }
}

然后,尝试查看它的字节码,我得到了以下public static void main函数的开头:

代码语言:javascript
复制
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: invokedynamic #3,  0              // InvokeDynamic #0:get:()Ljava/util/function/Supplier;
         5: astore_1
         6: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;

这里我们可以看到invokedynamic调用,如果我理解正确的话,它创建了Supplier接口的匿名实例。传递给invokedynamic的是两个参数,一个是#3,第二个参数是0。所以,我的第一个问题是:0在这里代表什么?

在常量池中,#3代表#3 = InvokeDynamic #0:#27 // #0:get:()Ljava/util/function/Supplier;。常量池中引用了#27,但没有引用#0。我的第二个问题是:#0在这里代表什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-28 17:51:21

#0 (您可以在invokedynamic旁边的注释中看到)实际上是BootstrapMethods表中的一个索引。所以第一个问题,0实际上指的是#0。而这又是BootstrapMethods表的索引。它提供了invokedynamic调用源和目标方法之间的链接。

如果你使用javap -c -v FileName进行反编译,你会看到整个常量池。(我假设你已经做到了?)在这里,您应该可以找到#X MethodHandle #y:#z IDDL.bootstrapDynamic的引用。这就是BootstrapMethods表链接到的点。#0链接到的句柄最终应解析为static bootstrapDynamic()方法。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38632794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档