模块  java.base
软件包  java.lang.invoke

Class StringConcatFactory


  • public final class StringConcatFactory
    extends Object

    方便创建字符串连接方法的方法,可用于有效地连接已知类型的已知类型的参数,可能在类型适配和参数的部分评估之后。 这些方法通常用作invokedynamic调用站点的引导方法 ,以支持Java编程语言的字符串连接功能。

    对提供的MethodHandle指定的行为的间接访问按顺序进行,分两个阶段:

    1. 调用此类中的方法时发生链接 它们将一个方法类型作为参数,描述连接的参数count和types,以及可选的String 配方 ,以及参与String连接的常量。 接受的食谱形状的细节将在下面进一步描述。 链接可能涉及动态加载实现预期级联行为的新类。 CallSite保持MethodHandle指向精确的连接方法。 串联方法可以在不同的CallSite之间共享,例如,如果链接方法将它们生成为纯函数。
    2. 当所生成的级联方法与精确动态参数调用发生调用 对于单个串联方法,这可能会发生多次。 使用静态参数和调用时提供的任何其他动态参数调用行为MethodHandle引用的方法,就像MethodHandle.invoke(Object...)一样

    这个类提供了两种形式的链接方法:一个只使用动态参数的简单版本( makeConcat(java.lang.invoke.MethodHandles.Lookup, String, MethodType) )和一个高级版本( makeConcatWithConstants(java.lang.invoke.MethodHandles.Lookup, String, MethodType, String, Object...)使用捕获常量参数的高级形式。高级策略可以产生略微更好的调用字节码,代价是爆炸在运行时出现的字符串连接方法的形状数量,因为这些形状也包括常量静态参数。

    API Note:

    有一个JVM限制(类文件结构约束):没有方法可以调用超过255个插槽。 这限制了可以传递给bootstrap方法的静态和动态参数的数量。 由于存在使用MethodHandle组合器的潜在级联策略,因此我们需要在参数列表上保留一些空插槽以捕获时间结果。 这就是为什么这个工厂中的bootstrap方法不接受超过200个参数槽的原因。 期望在串联中需要超过200个参数槽的用户将较大的串联拆分为较小的表达式。

    从以下版本开始:
    9
    • 方法详细信息

      • makeConcat

        public static CallSite makeConcat​(MethodHandles.Lookup lookup,
                                          String name,
                                          MethodType concatType)
                                   throws StringConcatException
        便于创建优化的字符串连接方法,可用于有效地连接已知类型的已知类型的参数,可能在类型调整和参数的部分评估之后。 通常用作invokedynamic调用站点的引导方法 ,以支持Java编程语言的字符串连接功能。

        当调用从此方法返回的CallSite的目标时,它返回字符串连接的结果,将传递给链接方法的所有函数参数作为连接的输入。 目标签名由concatType给出。 对于接受目标:

        • 零输入,连接导致空字符串;
        • 一个输入,串联结果在单个输入中按照JLS 5.1.11“字符串转换”进行转换; 除此以外
        • 两个或多个输入,输入按照JLS 15.18.1“字符串连接运算符+”中所述的要求连接。 输入按照JLS 5.1.11“字符串转换”进行转换,并从左到右进行组合。

        假设链接参数如下:

        • concatType ,描述了CallSite签名

        然后必须保持以下链接不变量:

        • concatType的参数槽数小于或等于200
        • concatType的返回类型可从String分配
        参数
        lookup - 表示具有调用lookup访问权限的查找上下文。 具体而言,查找上下文必须具有private access权限。 invokedynamic使用时,VM会自动堆叠。
        name - 要实现的方法的名称。 此名称是任意的,对此链接方法没有意义。 当与invokedynamic使用时,这由InvokeDynamic结构的NameAndType提供,并由VM自动堆叠。
        concatType -的的预期的签名CallSite 参数类型表示连接参数的类型; 返回类型始终可从String分配。 当与invokedynamic使用时,这由InvokeDynamic结构的NameAndType提供,并由VM自动堆叠。
        结果
        一个CallSite,其目标可用于执行字符串连接,具有给定 concatType描述的动态连接参数。
        异常
        StringConcatException - 如果违反了此处描述的任何链接不变量,或者查找上下文没有私有访问权限。
        NullPointerException - 如果任何传入参数为null。 使用invokedynamic调用bootstrap方法时,永远不会发生这种情况。
        See The Java™ Language Specification:
        5.1.11字符串转换,15.18.1字符串连接运算符+
      • makeConcatWithConstants

        public static CallSite makeConcatWithConstants​(MethodHandles.Lookup lookup,
                                                       String name,
                                                       MethodType concatType,
                                                       String recipe,
                                                       Object... constants)
                                                throws StringConcatException
        便于创建优化的字符串连接方法,可用于有效地连接已知类型的已知类型的参数,可能在类型调整和参数的部分评估之后。 通常用作invokedynamic调用站点的引导方法 ,以支持Java编程语言的字符串连接功能。

        当调用从此方法返回的CallSite的目标时,它返回String连接的结果,将传递给链接方法的所有函数参数和常量作为连接的输入。 目标签名由concatType给出,不包括常量。 对于接受目标:

        • 零输入,连接导致空字符串;
        • 一个输入,串联结果在单个输入中按照JLS 5.1.11“字符串转换”进行转换; 除此以外
        • 两个或多个输入,输入按照JLS 15.18.1“字符串连接运算符+”中所述的要求连接。 输入按照JLS 5.1.11“字符串转换”进行转换,并从左到右进行组合。

        连接配方是一个String描述,用于从参数和常量构造连接的String。 配方从左到右处理,每个字符代表连接的输入。 食谱字符意味着:

        • \ 1(Unicode点0001) :一个普通的参数。 此输入通过动态参数传递,并在连接方法调用期间提供。 此输入可以为null。
        • \ 2(Unicode点0002):一个常量。 此输入通过静态引导参数传递。 此常量可以是常量池中可表示的任何值。 如有必要,工厂将调用toString执行一次性字符串转换。
        • 任何其他char值:单个字符常量。

        假设链接参数如下:

        • concatType ,描述了CallSite签名
        • recipe ,描述字符串配方
        • constants ,常量的vararg数组

        然后必须保持以下链接不变量:

        • concatType的参数槽数小于或等于200
        • concatType的参数计数等于concatType的\ 1标记recipe
        • concatType的返回类型可从String分配,并匹配返回的MethodHandle的返回类型
        • constants的元素constants等于constants的\ 2标记recipe
        API Note:
        代码生成器有三种不同的方法来处理字符串连接表达式中的常量字符串操作数S. 首先,S可以实现为引用(使用ldc)并作为普通参数传递(配方'\ 1')。 或者,S可以存储在常量池中并作为常量传递(配方'\ 2')。 最后,如果S不包含任何配方标记字符('\ 1','\ 2'),则可以将S插入到配方本身中,从而将其字符插入到结果中。
        参数
        lookup - 表示具有调用lookup访问权限的查找上下文。 具体而言,查找上下文必须具有private access权限。 invokedynamic使用时,VM会自动堆叠。
        name - 要实现的方法的名称。 此名称是任意的,对此链接方法没有意义。 当与invokedynamic使用时,这由InvokeDynamic结构的NameAndType提供,并由VM自动堆叠。
        concatType -的的预期的签名CallSite 参数类型表示动态连接参数的类型; 返回类型始终可从String分配。 当与invokedynamic使用时,这由InvokeDynamic结构的NameAndType提供,并由VM自动堆叠。
        recipe - 如上所述的连接配方。
        constants - 表示传递给链接方法的常量的vararg参数。
        结果
        一个CallSite,其目标可用于执行字符串连接,具有给定 concatType描述的动态连接参数。
        异常
        StringConcatException - 如果违反了此处描述的任何链接不变量,或者查找上下文没有私有访问权限。
        NullPointerException - 如果任何传入参数为null,或recipe任何常量为null。 使用invokedynamic调用bootstrap方法时,永远不会发生这种情况。
        See The Java™ Language Specification:
        5.1.11字符串转换,15.18.1字符串连接运算符+