模块 java.base

类 StringConcatFactory

java.lang.Object
java.lang.invoke.StringConcatFactory

public final class StringConcatFactory extends Object

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

间接访问所提供的 MethodHandle 指定的行为通过两个阶段按顺序进行:

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

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

API 注意:

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

自从:
9
  • 方法详情

    • makeConcat

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

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

      • 零输入,连接结果为空字符串;
      • 一个输入,连接导致单个输入按照 JLS 5.1.11“字符串转换”进行转换;否则
      • 两个或多个输入,输入按照 JLS 15.18.1“字符串连接运算符 +”中规定的要求连接。输入按照 JLS 5.1.11“字符串转换”进行转换,并从左到右组合。

      假设链接参数如下:

      • concatType ,描述了 CallSite 签名

      那么下面的链接不变量必须成立:

      • concatType中的参数槽数小于等于200
      • concatType 中的返回类型可从 String 分配
      参数:
      lookup - 表示具有调用者可访问权限的查找上下文。具体来说,查找上下文必须有 完全权限访问 。当与 invokedynamic 一起使用时,它由 VM 自动堆叠。
      name - 要实现的方法的名称。这个名字是任意的,对于这个链接方法没有任何意义。当与 invokedynamic 一起使用时,它由 InvokeDynamic 结构的 NameAndType 提供,并由 VM 自动堆叠。
      concatType - CallSite 的预期签名。参数类型表示串联参数的类型;返回类型始终可从 String 分配。当与 invokedynamic 一起使用时,它由 InvokeDynamic 结构的 NameAndType 提供,并由 VM 自动堆叠。
      返回:
      一个 CallSite,其目标可用于执行字符串连接,动态连接参数由给定的 concatType 描述。
      抛出:
      StringConcatException - 如果违反了此处描述的任何链接不变量,或者查找上下文没有私有访问权限。
      NullPointerException - 如果任何传入参数为空。当使用 invokedynamic 调用引导程序方法时,这永远不会发生。
      Java 语言规范:
      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 调用站点的 bootstrap method,以支持 Java 编程语言的 string concatenation 功能。

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

      • 零输入,连接结果为空字符串;
      • 一个输入,连接导致单个输入按照 JLS 5.1.11“字符串转换”进行转换;否则
      • 两个或多个输入,输入按照 JLS 15.18.1“字符串连接运算符 +”中规定的要求连接。输入按照 JLS 5.1.11“字符串转换”进行转换,并从左到右组合。

      concatenation recipe 是一个 String 描述,描述了从参数和常量构造一个 concatenated String 的方法。配方是从左到右处理的,每个字符代表一个要连接的输入。配方字符表示:

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

      假设链接参数如下:

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

      那么下面的链接不变量必须成立:

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