需要解释CallSite是什么

4

CallSite文档中:

CallSite是一个存放变量MethodHandle的容器,该变量称为它的target。与CallSite关联的绑定到invokedynamic指令的所有调用都委托给站点的当前目标。一个CallSite可以与多个invokedynamic指令相关联,或者它可能是“自由漂浮”的,没有任何关联。无论如何,它都可以通过一个名叫动态调用器(dynamic invoker)的关联方法句柄来调用。

问题:

  1. CallSite中的target是否能被更改?如何更改?请提供一段代码示例。

  2. 答:
    是的,可以使用setTarget()方法更改 CallSite 中 target 的值。
    示例代码: ``` CallSite callsite = // some CallSite instance MethodHandles.Lookup lookup = // the lookup context MethodHandle mh = // new method handle to be used as the target callsite.setTarget(mh); // set the new target for the callsite instance ```
  3. 如何将CallSite与多个invokedynamic指令关联起来?

  4. 答:
    可以创建多个invokedynamic指令,每个指令都与CallSite关联。这样,每个 invokdedynamic 调用都会委托给CallSite的当前 target。
  5. 什么是“自由漂浮”的CallSite?如何创建这种实例?

  6. 答:
    自由漂浮的 CallSite 是指未与任何invokedynamic指令相关联的CallSite实例。可以通过调用LambdaMetafactory#altMetafactory()方法并传递 null 作为关联invokedynamic命令的参数来创建自由漂浮的CallSite实例。
    示例代码: ``` MethodHandles.Lookup lookup = // the lookup context MethodType invokedType = // the invoked type signature MethodHandle bootstrap = // the bootstrap method handle MethodHandle result = LambdaMetafactory.altMetafactory( lookup, "apply", MethodType.methodType(Function.class), invokedType, bootstrap, MethodType.methodType(CallSite.class) ).getTarget(); CallSite callsite = (CallSite) result.invokeExact(); // callsite is a free-floating CallSite instance ```
    注意:我想知道不同的编写代码/lambda的方式,以便在程序中出现这3个点。

3
已经得到回答。字面上回答其它问题: 2. 通过让引导方法多次返回相同的“CallSite”实例。 3. 每个“CallSite”对象最初都是自由浮动的,直到在“invokedynamic”链接过程中被引导方法返回。如果你从未在这样的过程中返回它,它将保持自由浮动状态。 - Holger
@Holger:现在很清楚了。你能否也回答一下我上一个评论中下面回答的问题? - Azodious
1
在那个评论中,你的问题不是很清楚。 - Holger
@Holger:我想知道当FunctionalInterface的单个抽象方法被调用时,调用如何转到解糖方法? - Azodious
2
正如其他评论所说,LambdaMetaFactory生成一个类。该类实现了接口,并具有调用目标方法的方法。 - Holger
1个回答

3
  1. 是的。在MutableCallSite或者VolatileCallSite中,可以通过CallSite#setTarget方法来更改目标。
  2. JVM规范的这一部分定义了如何初始化动态计算的CallSites。但为了回答这个问题,我认为这是有意设计的。也就是说,JVM规范要求JVM实现这样做,编译器可以利用它来提供优势。
  3. 您不会直接在代码中创建CallSites,因为编译器会自己创建它们,而且只是存在来说明可能有“自由飞行”的CallSites。

编辑:我认为您误解了文档,我认为您不应该直接从代码中初始化CallSite,因为这没有用处,文档的存在只是为了说明它的作用,而JVM使用它来为invokedynamic指令提供MethodHandle。


我的问题更多地是关于如何在代码中实现?正如您所说,CallSite不应该由开发人员创建,因此我想知道如何编写代码以使编译器执行这些3个点。 - Azodious
1
JSR的贡献者创建了CallSites和InvokeDynamic,旨在增强JVM对动态类型语言的支持。由于LambdaMetafactory仅创建ConstantCallSite,因此没有编译示例,建议您查看此答案。 - Deadbeef
由于LambdaMetafactory只创建ConstantCallSites,因此没有编译示例。您能分享一些链接来证明吗? - Azodious
太棒了。一个令人兴奋的问题:当说到“CallSite将返回”或“调用CallSite”时,这是什么意思?在获取CallSite对象后,当调用FunctionalInterface方法时,如何调用lambda desugared方法? - Azodious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接