モジュール java.base
パッケージ java.lang.invoke

クラスStringConcatFactory


  • public final class StringConcatFactory
    extends Object

    String連結メソッドの作成を容易にするためのメソッド。このメソッドを使用すると、既知の型の既知の数の引数を効率的に連結できます(場合によっては、型の適応および引数の部分評価の後)。 これらのメソッドは、通常、Javaプログラミング言語の文字列連結機能をサポートするために、 invokedynamicコール・サイトのブートストラップ・メソッドとして使用されます。

    指定された MethodHandleで指定された動作への間接アクセスは、次の2つのフェーズで順番に進みます。

    1. リンケージ。このクラスのメソッドが呼び出されたときに発生します。 これらは、引数として、連結された引数の数と型、およびオプションで文字列recipe、および文字列連結に参加する定数を記述するメソッド型を取ります。 受入済レシピ・シェイプの詳細は、後述します。 リンクには、予期される連結動作を実装する新しいクラスを動的にロードすることが含まれる場合があります。 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...))の2つの形式のリンケージ・メソッドを提供します。 高度な方法では、実行時に存在する文字列連結メソッドのシェイプの数が爆発する代償として、起動バイトコードが大幅に改善されることがあります。これは、これらのシェイプには定数静的引数も含まれるためです。

    APIのノート:

    JVMの制限(クラスファイルの構造的制約)があります。255個を超えるスロットを持つメソッドはコールできません。 これにより、ブートストラップ・メソッドに渡すことができる静的引数と動的引数の数が制限されます。 MethodHandleコンビネータを使用する可能性のある連結戦略があるため、時間的な結果を取得するには、パラメータ・リストにいくつかの空のスロットを予約する必要があります。 このため、このファクトリのブートストラップ・メソッドは、200を超える引数スロットを受け入れません。 連結で200を超える引数スロットを必要とするユーザーは、大きい連結を小さい式で分割する必要があります。

    導入されたバージョン:
    9
    • メソッドの詳細

      • makeConcat

        public static CallSite makeConcat​(MethodHandles.Lookup lookup,
                                          String name,
                                          MethodType concatType)
                                   throws StringConcatException
        最適化された文字列連結メソッドの作成を容易にします。このメソッドを使用すると、既知の型の既知の数の引数を効率的に連結できます(型の適応および引数の部分評価の後など)。 通常、Javaプログラミング言語の文字列連結機能をサポートするために、 invokedynamicコール・サイトのブートストラップ・メソッドとして使用されます。

        このメソッドから戻されたCallSiteのターゲットが呼び出されると、連結用の入力としてリンケージ・メソッドに渡されたすべての関数引数を取り、文字列連結の結果が返されます。 ターゲット・シグネチャは、concatTypeによって指定されます。 ターゲット受け入れの場合:

        • ゼロの入力、連結の結果は空の文字列になります。
        • 1つの入力と連結の結果、JLS 5.1.11「文字列変換」に従って変換された単一の入力になります。それ以外の場合は
        • 2つ以上の入力。入力は、JLS 15.18.1「文字列連結演算子+」に記載されている要件に従って連結されます。 入力はJLS 5.1.11「文字列変換」に従って変換され、左から右に結合されます。

        リンケージ引数は次のことを前提とします。

        • concatTypeCallSiteシグネチャの説明

        さらに、次のリンケージ不変条件を保持する必要があります。

        • concatTypeのパラメータ・スロットの数が200以下である
        • concatTypeの戻り型は、Stringから割当て可能です。

        パラメータ:
        lookup - コール元のアクセシビリティ権限を持つルックアップ・コンテキストを表します。 具体的には、ルックアップコンテキストには private access権限が必要です。 invokedynamicで使用されるときは、これはVMによって自動的にスタックされます。
        name - 実装するメソッドの名前。 この名前は任意であり、このリンク方法には意味がありません。 invokedynamicで使用されるときは、これはInvokeDynamic構造のNameAndTypeによって提供され、VMによって自動的にスタックされます。
        concatType - CallSiteの予期されるシグネチャ。 パラメータ型は連結引数の型を表し、戻り型は常にStringから割り当てることができます。 invokedynamicで使用されるときは、これは InvokeDynamic構造のNameAndTypeによって提供され、VMによって自動的にスタックされます。
        戻り値:
        指定されたconcatTypeで記述された動的連結引数を使用して、ターゲットを使用して文字列連結を実行できるCallSite。
        例外:
        StringConcatException - ここで説明するリンケージ不変条件に違反した場合、またはルックアップ・コンテキストにプライベート・アクセス権限がない場合。
        NullPointerException - 受信引数のいずれかがnullの場合。 起動動的でブートストラップ・メソッドが呼び出された場合、これは発生しません。
        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
        最適化された文字列連結メソッドの作成を容易にします。このメソッドを使用すると、既知の型の既知の数の引数を効率的に連結できます(型の適応および引数の部分評価の後など)。 通常、Javaプログラミング言語の文字列連結機能をサポートするために、 invokedynamicコール・サイトのブートストラップ・メソッドとして使用されます。

        このメソッドから戻されたCallSiteのターゲットが呼び出されると、文字列連結の結果が返され、連結の入力としてリンケージ・メソッドに渡されたすべての関数引数および定数が使用されます。 ターゲット・シグネチャは、concatTypeによって指定され、定数は含まれません。 ターゲット受け入れの場合:

        • ゼロの入力、連結の結果は空の文字列になります。
        • 1つの入力と連結の結果、JLS 5.1.11「文字列変換」に従って変換された単一の入力になります。それ以外の場合は
        • 2つ以上の入力。入力は、JLS 15.18.1「文字列連結演算子+」に記載されている要件に従って連結されます。 入力はJLS 5.1.11「文字列変換」に従って変換され、左から右に結合されます。

        連結recipeは、引数および定数から連結文字列を構築する方法を示す文字列の説明です。 レシピは左から右に処理され、各文字は連結への入力を表します。 レシピ文字の意味:

        • \\1 (Unicodeポイント0001): 通常の引数。 この入力は動的引数を介して渡され、連結メソッドの起動時に提供されます。 この入力はnullにできます。
        • \\2 (Unicodeポイント0002):定数。 この入力は、静的ブートストラップ引数を介して渡されます。 この定数は、定数プールで表現可能な任意の値にすることができます。 必要に応じて、ファクトリはtoStringをコールして、1回かぎりの文字列変換を実行します。
        • その他のchar値:単一の文字定数。

        リンケージ引数は次のことを前提とします。

        • concatTypeCallSiteシグネチャの説明
        • recipe、文字列レシピの説明
        • constants: 定数のvararg配列

        さらに、次のリンケージ不変条件を保持する必要があります。

        • concatTypeのパラメータ・スロットの数が200以下である
        • concatTypeのパラメータ数は、recipeの\\1タグの数と同じです
        • concatTypeの戻り型は、Stringから割当て可能で、戻されたMethodHandleの戻り型と一致します。
        • constantsの要素数は、recipeの\\2タグの数に等しくなります。

        APIのノート:
        コード・ジェネレータには、文字列連結式で定数文字列オペランドSを処理する3つの異なる方法があります。 まず、Sは参照として(ldcを使用して)実体化し、通常の引数(レシピ'\\1')として渡すことができます。 または、Sを定数プールに格納し、定数(レシピ'\\2')として渡すことができます。 最後に、Sにいずれのレシピ・タグ文字('\\1'、 '\\2')も含まれていない場合、Sをレシピ自体に補間することで、その文字を結果に挿入できます。
        パラメータ:
        lookup - コール元のアクセシビリティ権限を持つルックアップ・コンテキストを表します。 具体的には、ルックアップコンテキストには private access権限が必要です。 invokedynamicで使用されるときは、これはVMによって自動的にスタックされます。
        name - 実装するメソッドの名前。 この名前は任意であり、このリンク方法には意味がありません。 invokedynamicで使用されるときは、これはInvokeDynamic構造のNameAndTypeによって提供され、VMによって自動的にスタックされます。
        concatType - CallSiteの予期されるシグネチャ。 パラメータ型は動的連結引数の型を表し、戻り型は常にStringから割り当てることができます。 invokedynamicで使用されるときは、これはInvokeDynamic構造の NameAndTypeによって提供され、VMによって自動的にスタックされます。
        recipe - 前述の連結レシピ。
        constants - linkageメソッドに渡される定数を表すvarargパラメータ。
        戻り値:
        指定されたconcatTypeで記述された動的連結引数を使用して、ターゲットを使用して文字列連結を実行できるCallSite。
        例外:
        StringConcatException - ここで説明するリンケージ不変条件に違反した場合、またはルックアップ・コンテキストにプライベート・アクセス権限がない場合。
        NullPointerException - いずれかの着信引数がnullの場合、またはrecipeの定数がすべてnullの場合。 起動動的でブートストラップ・メソッドが呼び出された場合、これは発生しません。
        The Java™Language Specificationを参照してください。
        5.1.11文字列変換、 15.18.1文字列連結演算子+