模块 jdk.dynalink

类 DynamicLinker

java.lang.Object
jdk.dynalink.DynamicLinker

public final class DynamicLinker extends Object
RelinkableCallSite 对象的链接器。动态链接器是使用 Dynalink 时的主要对象,它协调调用站点与由 GuardingDynamicLinker 对象表示的可用语言运行时的链接器的链接(如果您自己使用自己的对象模型实现语言运行时,则只需要处理这些和/或类型转换)。要使用 Dynalink,您必须使用 DynamicLinkerFactory 创建一个或多个动态链接器。随后,您需要从 invokedynamic 引导方法调用它的 link(RelinkableCallSite) 方法,让它管理它们创建的所有调用站点。通常的用法是为每个语言运行时创建至少一个类以包含一个链接器实例,如:
 class MyLanguageRuntime {
   private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
   private static final DynamicLinker dynamicLinker = createDynamicLinker();

   private static DynamicLinker createDynamicLinker() {
     final DynamicLinkerFactory factory = new DynamicLinkerFactory();
     factory.setPrioritizedLinker(myLanguageLinker);
     return factory.createLinker();
   }

   public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
     return dynamicLinker.link(
       new SimpleRelinkableCallSite(
         new CallSiteDescriptor(lookup, parseOperation(name), type)));
   }

   private static Operation parseOperation(String name) {
     ...
   }
 }
 
一个静态链接器实例的上述设置通常过于简单。您通常会让您的语言运行时有某种“上下文类加载器”的概念,并且您会希望为每个此类加载器创建一个动态链接器,以确保它包含该类加载器可见的所有其他语言运行时的链接器(请参阅DynamicLinkerFactory.setClassLoader(ClassLoader) )。

在上面的示例中,您需要提供三个组件:

  • 您需要为自己的语言提供 GuardingDynamicLinker 。如果您的运行时没有自己的对象模型或类型转换,则不需要实现 GuardingDynamicLinker ;您根本不会在工厂上调用 setPrioritizedLinker 方法。
  • 程序的性能取决于您选择的类来表示调用站点。上面的示例使用了 SimpleRelinkableCallSite ,但您可能想改用 ChainedCallSite 。您需要进行试验并确定最适合您的运行时的方法。您可以进一步子类化其中任何一个或实现您自己的。
  • 您还需要向呼叫站点提供 CallSiteDescriptor s。它们是不可变对象,包含有关调用站点的所有信息:执行查找的类、被调用的操作和方法签名。您将必须提供自己的方案以在调用站点名称或静态参数中编码和解码操作,这就是为什么在上面的示例中未实现 parseOperation 方法的原因。
  • 方法详情

    • link

      public <T extends RelinkableCallSite > T link(T callSite)
      链接一个 invokedynamic 调用站点。它将在调用此链接器的重新链接机制的调用站点中安装一个方法句柄。下次调用调用站点时,它将链接到调用时使用的实际参数。
      类型参数:
      T - 要为其创建链接的 RelinkableCallSite 的特定子类。
      参数:
      callSite - 要链接的呼叫站点。
      返回:
      callSite,用于轻松调用链接。
    • getLinkerServices

      public LinkerServices  getLinkerServices()
      返回表示此类链接器服务的对象,这些链接器服务通常暴露给个人 language-specific linkers 。作为此类的用户,您通常只关心 link(RelinkableCallSite) 方法,但在某些情况下您可能希望直接使用较低级别的服务;要么查找特定的方法句柄,要么访问类型转换器,等等。
      返回:
      表示此类链接器服务的对象。
    • getLinkedCallSiteLocation

      public static StackTraceElement  getLinkedCallSiteLocation()
      返回描述当前线程上链接的 invokedynamic 调用站点位置的堆栈跟踪元素。该操作可能代价高昂,因为它需要生成堆栈跟踪以对其进行检查,并且旨在用于诊断代码。对于“自由浮动”调用站点(与 invokedynamic 指令无关),结果未明确定义。
      返回:
      描述当前链接的调用站点位置的堆栈跟踪元素,如果在链接调用站点时未调用它,则为 null。