Module jdk.dynalink
Package jdk.dynalink

Class 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。它们是不可变对象,包含有关调用站点的所有信息:执行查找的类、正在调用的操作和方法签名。您将不得不提供自己的方案来编码和解码调用站点名称或静态参数中的操作,这就是为什么在上面的示例中parseOperation方法未实现。
  • Method Details

    • link

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

      public LinkerServices getLinkerServices()
      返回表示此类的链接器服务的对象,通常向单独的特定于语言的链接器公开。作为此类的用户,您通常只关心link(RelinkableCallSite)方法,但在某些情况下,您可能希望直接使用较低级别的服务;要么查找特定方法句柄,要么访问类型转换器等。
      返回:
      表示此类的链接器服务的对象。
    • getLinkedCallSiteLocation

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