模块  jdk.dynalink
软件包  jdk.dynalink

Class DynamicLinker


  • public final class DynamicLinker
    extends Object
    RelinkableCallSite对象的链接器。 动态链接器是使用Dynalink时的主要对象,它协调调用站点与由GuardingDynamicLinker对象表示的可用语言运行时的链接器的链接(如果您自己使用自己的对象模型实现语言运行时,则只需要处理这些对象)和/或类型转换)。 要使用Dynalink,您必须使用DynamicLinkerFactory创建一个或多个动态链接器。 随后,您需要从invokedynamic引导方法调用其link(RelinkableCallSite)方法, invokedynamic管理它们创建的所有调用站点。 通常的用法是每个语言运行时至少创建一个类,以包含一个链接器实例:
      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方法未实现的原因。
    • 方法详细信息

      • 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指令invokedynamic ),结果没有明确定义。
        结果
        描述当前链接的调用站点位置的堆栈跟踪元素,如果在链接调用站点时未调用它,则返回null。