模块 java.base

类 CallSite

java.lang.Object
java.lang.invoke.CallSite
已知子类:
ConstantCallSite , MutableCallSite , VolatileCallSite

public abstract sealed class CallSite extends Object permits ConstantCallSite , MutableCallSite , VolatileCallSite
CallSite 是变量 MethodHandle 的持有者,称为它的 target。链接到 CallSiteinvokedynamic 指令将所有调用委托给站点的当前目标。一个 CallSite 可能与多个 invokedynamic 指令相关联,或者它可能是“自由浮动”的,没有相关联。在任何情况下,它都可以通过名为 动态调用程序 的关联方法句柄调用。

CallSite 是一个抽象密封类,不允许用户直接子类化。它具有三个直接的、具体的非密封子类,可以实例化或子类化。

  • 如果不需要可变目标,可以通过 持续呼叫站点 永久绑定 invokedynamic 指令。
  • 如果需要具有易变变量语义的可变目标,因为对目标的更新必须立即可靠地由其他线程见证,可以使用 不稳定的呼叫站点
  • 否则,如果需要可变目标,则可以使用 可变调用站点

一个不固定的呼叫站点可能是relinked通过改变它的目标。新目标必须与之前的目标具有相同的type。因此,尽管调用站点可以重新链接到一系列连续的目标,但它不能更改其类型。

以下是调用站点和引导方法的示例使用,它链接每个动态调用站点以打印其参数:


static void test() throws Throwable {
  // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
  InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
}
private static void printArgs(Object... args) {
 System.out.println(java.util.Arrays.deepToString(args));
}
private static final MethodHandle printArgs;
static {
 MethodHandles.Lookup lookup = MethodHandles.lookup();
 Class thisClass = lookup.lookupClass(); // (who am I?)
 printArgs = lookup.findStatic(thisClass,
   "printArgs", MethodType.methodType(void.class, Object[].class));
}
private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
 // ignore caller and name, but match the type:
 return new ConstantCallSite(printArgs.asType(type));
}
 
密封类层次结构图:
Sealed class hierarchy graph for CallSiteSealed class hierarchy graph for CallSite
自从:
1.7