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

クラスStringConcatFactory


  • public final class StringConcatFactory
    extends Object

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

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

    1. リンケージ。このクラスのメソッドが呼び出されたときに発生します。 それらは、連結された引数の数と型、およびオプションでString recipeと、String連結に関与する定数を記述するメソッド型を引数として取ります。 受け入れられたレシピ・シェイプに関する詳細は、以下でさらに説明されます。 リンケージには、予想される連結動作を実装する新しいクラスを動的にロードする必要があります。 CallSiteは、正確な連結メソッドを指すMethodHandleを保持します。 連結メソッドは、例えば、連結メソッドがそれらを純粋な関数として生成する場合、異なるCallSite間で共有することができます。
    2. 「呼び出し」は、生成された連結メソッドが正確な動的引数で呼び出されたときに発生します。 これは、1回の連結メソッドで何度も発生することがあります。 ビヘイビア MethodHandleによって参照されるメソッドは、MethodHandle.invoke(Object...)の場合と同様に、静的引数および呼び出し時に追加された追加の動的引数で呼び出されます。

    このクラスは、2つの形式のリンケージ・メソッド: 動的引数のみを使用する単純なバージョンの(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呼び出しサイト用の「ブートストラップ法」として使用され、Javaプログラミング言語の「文字列連結」機能をサポートします。

        このメソッドから返されたCallSiteのターゲットが呼び出されると、連結のための入力としてリンケージ・メソッドに渡されたすべての関数引数を取り、ストリング連結の結果を返します。 ターゲット・シグネチャはconcatTypeで与えられます。 受け入れ対象:

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

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

        • concatTypeCallSiteのシグネチャを記述

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

        • concatTypeのパラメータ・スロットの数が200以下です
        • concatTypeの戻り値の型はStringから代入可能です。

        パラメータ:
        lookup - 呼び出し元のアクセシビリティ権限を持つ参照コンテキストを表します。 具体的には、ルックアップ・コンテキストには「プライベート・アクセス」特権が必要です。 invokedynamicで使用されるときは、これはVMによって自動的にスタックされます。
        name - 実装するメソッドの名前。 この名前は任意であり、このリンク・メソッドには意味がありません。 invokedynamicで使用されるときは、これはInvokeDynamic構造のNameAndTypeによって提供され、VMによって自動的にスタックされます。
        concatType - CallSiteの予想されるシグネチャ。 パラメータ型は、連結引数の型を表します。戻り値の型は常にStringから割り当て可能です。 invokedynamicで使用されるときは、これは InvokeDynamic構造のNameAndTypeによって提供され、VMによって自動的にスタックされます。
        戻り値:
        指定されたconcatTypeで記述された動的連結引数を使用して、ターゲットを使用して文字列連結を実行できるCallSite。
        例外:
        StringConcatException - ここで説明されているリンケージ不変条件のいずれかに違反があるか、ルックアップ・コンテキストにプライベート・アクセス権限がない場合。
        NullPointerException - 入ってくる引数のいずれかがnullの場合。 これは、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呼び出しサイト用の「ブートストラップ法」として使用され、Javaプログラミング言語の「文字列連結」機能をサポートします。

        このメソッドから返されたCallSiteのターゲットが呼び出されると、連結のための入力としてリンケージ・メソッドに渡されたすべての関数引数と定数を取って、String連結の結果を返します。 ターゲット・シグネチャはconcatTypeで与えられ、定数は含まれません。 受け入れ対象:

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

        連結recipeは、引数と定数から連結されたStringを構築するためのString記述です。 レシピは左から右に処理され、各文字は連結の入力を表します。 レシピ文字の意味:

        • \1 (Unicodeポイント0001): 普通の議論。 この入力は動的引数を介して渡され、連結メソッド呼び出し中に提供されます。 この入力はnullでもかまいません。
        • \2 (Unicodeポイント0002):定数。 この入力は、静的ブートストラップ引数を通過しました。 この定数は、定数プールで表現可能な任意の値にすることができます。 必要に応じて、ファクトリはtoStringを呼び出してワンタイム・ストリング変換を実行します。
        • その他のchar値: 単一の文字定数です。

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

        • concatTypeCallSiteのシグネチャを記述
        • recipe、文字列のレシピを記述
        • constants、定数の可変配列

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

        • concatTypeのパラメータ・スロットの数が200以下です
        • concatTypeのパラメータ数は、recipeの\1タグの数と等しくなります
        • concatTypeの戻り値の型はStringから代入可能で、返されるMethodHandleの戻り値の型と一致
        • constantsの要素の数は、recipeの\2タグの数と等しくなります

        APIの注:
        コード・ジェネレータは、文字列連結式で定数の文字列オペランドSを処理する3つの異なる方法を持っています。 まず、Sを参照(ldcを使用して)として実現し、通常の引数(レシピ'\1')として渡すことができます。 あるいは、Sを定数プールに格納して定数(レシピ'\2')として渡すこともできます。 最後に、Sにレシピ・タグ文字('\1', '\2')のいずれも含まれていない場合、Sはレシピ自体に補間され、その文字が結果に挿入されます。
        パラメータ:
        lookup - 呼び出し元のアクセシビリティ権限を持つ参照コンテキストを表します。 具体的には、ルックアップ・コンテキストには「プライベート・アクセス」特権が必要です。 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の場合。 これは、invokedynamicでブートストラップ・メソッドが呼び出されたときには起こりません。
        Java™言語仕様:
        5.1.11文字列変換、15.18.1文字列連結演算子+