public final class LambdaMetafactory extends Object
おそらく型適応と引数の部分評価の後に、指定されたMethodHandle
への委譲によって、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にするメソッド。 これらのメソッドは一般に、invokedynamic
コール・サイトのブートストラップ・メソッドとして使用され、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートします。
提供されたMethodHandle
によって指定された動作への間接アクセスは、3つのフェーズで順番に進行します。
- リンケージ。このクラスのメソッドが呼び出されたときに発生します。 これらは引数として、実装されるインタフェース(一般的に関数型インタフェース、単一抽象メソッドを持つもの)、実装されるそのインタフェースからのメソッドの名前とシグネチャ、そのメソッドに求められる実装動作を記述するメソッド・ハンドルを取り(他の追加メタデータを取ることもある)、ターゲットを適切な関数オブジェクトを作成するために使用できる
CallSite
を生成します。 リンケージでは、ターゲット・インタフェースを実装する新しいクラスが動的にロードされることもあります。CallSite
は関数オブジェクトのファクトリと見なすことができるため、これらのリンケージ・メソッドはメタファクトリと呼ばれます。 - キャプチャ。
CallSite
のターゲットが呼び出されるときに発生し(一般的にinvokedynamic
コール・サイトによって)、関数オブジェクトを生成します。 これは、単一ファクトリCallSite
に対して何度も発生する場合があります。 キャプチャでは、新しい関数オブジェクトが割り当てられたり、既存の関数オブジェクトを返したりすることもあります。 動作MethodHandle
には、指定されたインタフェース・メソッドのパラメータ以外に追加パラメータが指定される場合があります。これらはキャプチャ・パラメータと呼ばれ、CallSite
ターゲットへの引数として指定される必要があり、動作MethodHandle
に早期バインドされる場合があります。 キャプチャ・パラメータの数および型はリンケージ中に決定されます。CallSite
ターゲットの呼出しにより生成された関数オブジェクトのアイデンティティは予測できないため、アイデンティティに依存する操作(参照の等価性、オブジェクトのロック、System.identityHashCode()
など)は、異なる実装や同じ実装での異なる呼出し時に生成される可能性があります。 - 呼出し。実装されたインタフェース・メソッドが関数オブジェクトで呼び出されたときに発生します。 これは、単一関数オブジェクトに対して何度も発生する場合があります。 動作
MethodHandle
によって参照されるメソッドは、MethodHandle.invoke(Object...)
による場合と同様に、キャプチャ引数と呼出しで指定される追加引数を使用して呼び出されます。
呼出しで許可される入力または結果のセットを制限することが便利な場合があります。 たとえば、ジェネリック・インタフェースPredicate<T>
がPredicate<String>
としてパラメータ化されるときは、入力はString
である必要があります(実装するメソッドが任意のObject
を許可していても)。 リンケージで、追加のMethodType
パラメータがインスタンス化されたメソッド型を記述するとします。すると呼出しで、引数と最終的な結果がこのMethodType
に基づいてチェックされます。
このクラスは2つの形式のリンケージ・メソッドを提供します。最適化されたプロトコルを使用する標準版(metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)
)と、代替版(altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
)です。 代替版は標準版の一般化したもので、フラグおよび追加引数を介して生成された関数オブジェクトの動作に対する追加制御を提供します。 代替版では、関数オブジェクトの次の属性を管理する機能が追加されます。
- ブリッジング。 引数または戻り型の適応を含む、メソッド・シグネチャの複数のバリエーションを実装するのに役立つ場合があります。 これは、メソッドの複数の異なるVMシグネチャが、言語によって論理的に同じメソッドであると見なされるときに発生します。 フラグ
FLAG_BRIDGES
は、追加のMethodType
のリストが提供されることを示します(それぞれが結果の関数オブジェクトによって実装される)。 これらのメソッドは同じ名前およびインスタンス化された型を共有します。 - 複数のインタフェース。 必要に応じて、関数オブジェクトは複数のインタフェースを実装できます。 (これらの追加インタフェースは一般的に、メソッドなしのマーカー・インタフェースです。) フラグ
FLAG_MARKERS
は、追加インタフェースのリストが提供されることを示します(それぞれが結果の関数オブジェクトによって実装される)。 - 直列化可能性。 生成された関数オブジェクトは一般的に直列化をサポートしません。 必要に応じて、関数オブジェクトが直列化可能であるべきことを示すために
FLAG_SERIALIZABLE
を使用できます。 直列化可能関数オブジェクトは、キャプチャ・クラス(MethodHandles.Lookup
のパラメータcaller
によって記述されるクラス)からの追加支援を必要とする、SerializedLambda
クラスのインスタンスを、直列化形式として使用します。詳細は、SerializedLambda
を参照してください。
リンケージ引数は次のことを前提とします。
invokedType
(CallSite
シグネチャを記述)は、型(D1..Dk)および戻り型RdのKパラメータを持つ。samMethodType
(実装されたメソッド型を記述)は、型(U1..Un)および戻り型RuのNパラメータを持つ。implMethod
(実装を提供するMethodHandle
)は、型(A1..Am)および戻り型RaのMパラメータを持つ(メソッドがインスタンス・メソッドを記述する場合、このメソッド・ハンドルのメソッド型はレシーバに対応する追加の最初の引数をすでに含む)。instantiatedMethodType
(呼出しでの制限を許可)は、型(T1..Tn)および戻り型RtのNパラメータを持つ。
さらに、次のリンケージ不変条件を保持する必要があります。
- Rdがインタフェース
implMethod
が直接メソッド・ハンドルsamMethodType
およびinstantiatedMethodType
が同じ引数カウントNを持つ、およびi=1..Nの場合にTiおよびUiが同じ型、またはTiおよびUiが両方とも参照型かつTiがUiのサブタイプ- RtおよびRuが同じ型、または両方が参照型かつRtがRuのサブタイプ
- K + N = M
- i=1..Kの場合、Di = Ai
- i=1..Nの場合、TiはAjに適応可能、j=i+k
- 戻り型Rtがvoid、または戻り型RaがvoidでなくRtに適応可能
さらに、キャプチャ時は、implMethod
がインスタンス・メソッドに対応し、キャプチャ引数(K > 0
)が存在し、最初のキャプチャ引数(レシーバに対応する)は非nullである必要があります。
次のように型QはSに適応可能と見なされます。
Q | S | リンク時チェック | 呼出し時チェック |
---|---|---|---|
プリミティブ | プリミティブ | Qはプリミティブ・ワイドニング変換でSに変換可能 | なし |
プリミティブ | 参照 | SはWrapper(Q)のスーパータイプ | Wrapper(Q)からSにキャスト |
参照 | プリミティブ | パラメータ型の場合: Qはプリミティブ・ラッパー、Primitive(Q)はSにワイドニング可能 戻り型の場合: Qがプリミティブ・ラッパーの場合はPrimitive(Q)がSにワイドニング可能かをチェック |
Qがプリミティブ・ラッパーでない場合、Qを基底Wrapper(S)にキャスト。たとえば、数値型の場合はNumber |
参照 | 参照 | for parameter types: S is a supertype of Q for return types:なし |
QからSにキャスト |
- APIの注:
- これらのリンケージ・メソッドはJava言語のラムダ式およびメソッド参照の評価をサポートするように設計されています。 ソース・コード内のすべてのラムダ式またはメソッド参照に、関数型インタフェースであるターゲット型が存在します。 ラムダ式を評価することで、そのターゲット型のオブジェクトが生成されます。 ラムダ式の評価で推奨されるメカニズムは、メソッドのラムダ本文を脱糖し、invokedynamicコール・サイト(静的引数リストが関数型インタフェースの唯一のメソッドおよび脱糖された実装メソッドを記述し、ターゲット型を実装するオブジェクト(ラムダ・オブジェクト)を返す)を呼び出すことです。 (メソッド参照の場合、実装メソッドは単に参照されるメソッドです、脱糖は必要ありません。)
実装メソッドの引数リストとインタフェース・メソッドの引数リストはいくつかの点で異なる場合があります。 実装メソッドは、ラムダ式によってキャプチャされる引数に対応するために追加引数を持つ場合があります。引数に許可された適応(キャスト、ボクシング、アンボクシング、プリミティブ・ワイドニングなど)による違いがある場合もあります。 (可変引数適応はメタファクトリによって扱われません。これらは呼出し元によって扱われることが期待されます。)
invokedynamicコール・サイトには2つの引数リスト、静的引数リストと動的引数リストがあります。 静的引数リストは定数プールに格納されますが、動的引数はキャプチャ時にオペランド・スタックにプッシュされます。 ブートストラップ・メソッドは、静的引数リスト全体(この場合、実装メソッド、ターゲット・インタフェースおよびターゲット・インタフェース・メソッドを記述する情報を含む)、動的引数の数と静的な型(ただし値ではない)およびinvokedynamicサイトの静的な戻り型を記述するメソッド・シグネチャにアクセスできます。
- 実装上の注意:
- 実装メソッドはメソッド・ハンドルで記述されます。 理論上は、任意のメソッド・ハンドルを使用できます。 ただし、現在サポートされているのは、仮想、インタフェース、コンストラクタおよび静的メソッドの呼出しを表す直接メソッド・ハンドルです。
- 導入されたバージョン:
- 1.8
-
フィールドのサマリー
フィールド 修飾子と型 フィールド 説明 static int
FLAG_BRIDGES
ラムダ・オブジェクトが追加のブリッジ・メソッドを必要としていることを示す、代替メタファクトリ用のフラグstatic int
FLAG_MARKERS
ラムダ・オブジェクトがSerializable以外に他のマーカー・インタフェースを実装することを示す、代替メタファクトリ用のフラグstatic int
FLAG_SERIALIZABLE
ラムダ・オブジェクトが直列化可能である必要があることを示す、代替メタファクトリ用のフラグ -
メソッドのサマリー
修飾子と型 メソッド 説明 static CallSite
altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args)
適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。static CallSite
metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType)
適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。
-
フィールド詳細
-
FLAG_SERIALIZABLE
public static final int FLAG_SERIALIZABLEラムダ・オブジェクトが直列化可能である必要があることを示す、代替メタファクトリ用のフラグ- 関連項目:
- 定数フィールド値
-
FLAG_MARKERS
public static final int FLAG_MARKERSラムダ・オブジェクトがSerializable以外に他のマーカー・インタフェースを実装することを示す、代替メタファクトリ用のフラグ- 関連項目:
- 定数フィールド値
-
FLAG_BRIDGES
public static final int FLAG_BRIDGESラムダ・オブジェクトが追加のブリッジ・メソッドを必要としていることを示す、代替メタファクトリ用のフラグ- 関連項目:
- 定数フィールド値
-
-
メソッドの詳細
-
metafactory
public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType) throws LambdaConversionException適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。 一般的にinvokedynamic
コール・サイトのブートストラップ・メソッドとして、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートするために使用されます。これは標準の、合理化されたメタファクトリです。
altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
によってより高い柔軟性が提供されます。 このメソッドの動作の概要はすでに説明
済です。このメソッドから返される
CallSite
のターゲットが呼び出されると、結果の関数オブジェクトは、invokedType
の戻り型で指定されるインタフェースを実装し、かつinvokedName
で指定される名前とsamMethodType
で指定されるシグネチャを持つメソッドを宣言する、クラスのインスタンスです。Object
からの追加メソッドをオーバーライドすることもできます。- パラメータ:
caller
- 呼出し元のアクセス可能性権限を持つルックアップ・コンテキストを表します。 具体的には、ルックアップ・コンテキストには「プライベート・アクセス」特権が必要です。invokedynamic
で使用されるときは、これはVMによって自動的にスタックされます。invokedName
- 実装するメソッドの名前。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。invokedType
-CallSite
の期待されるシグネチャ。 パラメータ型はキャプチャ変数の型を表し、戻り型は実装するインタフェースです。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。 実装メソッドがインスタンス・メソッドで、このシグネチャがパラメータを持つ場合は、呼出しシグネチャの最初のパラメータはレシーバに対応する必要があります。samMethodType
- 関数オブジェクトによって実装されるメソッドのシグネチャおよび戻り型。implMethod
- 呼出しで(引数型および戻り型が適切に適応され、キャプチャ引数に呼出し引数が付加された状態で)呼び出される実装メソッドを記述する直接メソッド・ハンドル。instantiatedMethodType
- 呼出しで動的に適用されるシグネチャおよび戻り型。 これは、samMethodType
と同じ場合、またはその特殊化の場合があります。- 戻り値:
- CallSite。そのターゲットを使用してキャプチャを実行し、
invokedType
で指定されるインタフェースのインスタンスを生成できる - 例外:
LambdaConversionException
-above
で説明されているリンケージ不変条件のいずれかに違反がある場合、またはルックアップ・コンテキストにプライベート・アクセス権限がない場合。
-
altMetafactory
public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws LambdaConversionException適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。 一般的にinvokedynamic
コール・サイトのブートストラップ・メソッドとして、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートするために使用されます。これは一般的で、柔軟性の高いメタファクトリです。合理化されたバージョンが
metafactory(java.lang.invoke.MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)
によって提供されます。 このメソッドの動作の概要はすでに説明
済です。このメソッドの引数リストには3つの固定パラメータが含まれ、
invokedynamic
呼出しでブートストラップ・メソッドのためにVMによって自動的にスタックされるパラメータと、追加パラメータを含むObject[]
パラメータに対応しています。 このメソッドに宣言される引数リストは次のとおりです。CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args)
しかし、引数リストが以下であるかのように動作します。
CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, int flags, int markerInterfaceCount, // IF flags has MARKERS set Class... markerInterfaces, // IF flags has MARKERS set int bridgeCount, // IF flags has BRIDGES set MethodType... bridges // IF flags has BRIDGES set )
metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)
の引数リスト内の引数は、そのメソッド内と同じ仕様を持ちます。 追加引数は次のように解釈されます。flags
は追加オプションを示します。これは、必要なフラグのビット単位ORです。 定義済フラグはFLAG_BRIDGES
、FLAG_MARKERS
およびFLAG_SERIALIZABLE
です。markerInterfaceCount
は関数オブジェクトが実装する追加インタフェースの数で、FLAG_MARKERS
フラグが設定されている場合にのみ存在します。markerInterfaces
は実装する追加インタフェースの可変長リストで、その長さはmarkerInterfaceCount
と等しく、FLAG_MARKERS
フラグが設定されている場合にのみ存在します。bridgeCount
は関数オブジェクトが実装する追加メソッド・シグネチャの数で、FLAG_BRIDGES
フラグが設定されている場合にのみ存在します。bridges
は実装する追加メソッド・シグネチャの可変長リストで、その長さはbridgeCount
と等しく、FLAG_BRIDGES
フラグが設定されている場合にのみ存在します。
markerInterfaces
で指定される各クラスには、前述
のinvokedType
の戻り型、Rd
と同じ制限が適用されます。bridges
で指定される各MethodType
には、前述
のsamMethodType
と同じ制限が適用されます。flags
にFLAG_SERIALIZABLEが設定されているとき、関数オブジェクトはSerializable
を実装し、適切なSerializedLambda
を返すwriteReplace
メソッドを持ちます。caller
クラスは、SerializedLambda
で説明したとおり適切な$deserializeLambda$
メソッドを持つ必要があります。このメソッドから返される
CallSite
のターゲットが呼び出されるとき、結果の関数オブジェクトは次のプロパティを持つクラスのインスタンスです。- このクラスは
invokedType
の戻り型で指定されるインタフェースと、markerInterfaces
で指定されるインタフェースを実装します。 - このクラスは
invokedName
で指定される名前、samMethodType
で指定されるシグネチャ、およびbridges
で指定される追加シグネチャでメソッドを宣言します。 - このクラスは
Object
からのメソッドをオーバーライドでき、直列化に関連するメソッドを実装できます。
- パラメータ:
caller
- 呼出し元のアクセス可能性権限を持つルックアップ・コンテキストを表します。 具体的には、ルックアップ・コンテキストには「プライベート・アクセス」特権が必要です。invokedynamic
で使用されるときは、これはVMによって自動的にスタックされます。invokedName
- 実装するメソッドの名前。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。invokedType
-CallSite
の期待されるシグネチャ。 パラメータ型はキャプチャ変数の型を表し、戻り型は実装するインタフェースです。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。 実装メソッドがインスタンス・メソッドで、このシグネチャがパラメータを持つ場合は、呼出しシグネチャの最初のパラメータはレシーバに対応する必要があります。args
- 前述のaltMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
の説明のとおり、必要な引数samMethodType
、implMethod
、instantiatedMethodType
およびflags
とオプション引数を含むObject[]
配列- 戻り値:
- CallSite。そのターゲットを使用してキャプチャを実行し、
invokedType
で指定されるインタフェースのインスタンスを生成できる - 例外:
LambdaConversionException
-above
で説明されているリンケージ不変条件のいずれかに違反がある場合、またはルックアップ・コンテキストにプライベート・アクセス権限がない場合。
-