public class LambdaMetafactory extends Object
おそらく型適応と引数の部分評価の後に、指定されたMethodHandleへの委譲によって、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にするメソッド。これらのメソッドは一般に、invokedynamicコール・サイトのブートストラップ・メソッドとして使用され、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートします。
提供されたMethodHandleによって指定された動作への間接アクセスは、3つのフェーズで順番に進行します。
CallSiteを生成します。リンケージでは、ターゲット・インタフェースを実装する新しいクラスが動的にロードされることもあります。CallSiteは関数オブジェクトのファクトリと見なすことができるため、これらのリンケージ・メソッドはメタファクトリと呼ばれます。CallSiteのターゲットが呼び出されるときに発生し(一般的にinvokedynamicコール・サイトによって)、関数オブジェクトを生成します。これは、単一ファクトリCallSiteに対して何度も発生する場合があります。キャプチャでは、新しい関数オブジェクトが割り当てられたり、既存の関数オブジェクトを返したりすることもあります。動作MethodHandleには、指定されたインタフェース・メソッドのパラメータ以外に追加パラメータが指定される場合があります。これらはキャプチャ・パラメータと呼ばれ、CallSiteターゲットへの引数として指定される必要があり、動作MethodHandleに早期バインドされる場合があります。キャプチャ・パラメータの数および型はリンケージ中に決定されます。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...))です。代替版は標準版の一般化したもので、フラグおよび追加引数を介して生成された関数オブジェクトの動作に対する追加制御を提供します。代替版では、関数オブジェクトの次の属性を管理する機能が追加されます。
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パラメータを持つ。さらに、次のリンケージ不変条件を保持する必要があります。
implMethodが直接メソッド・ハンドルsamMethodTypeおよびinstantiatedMethodTypeが同じ引数カウントNを持つ、およびi=1..Nの場合にTiおよびUiが同じ型、またはTiおよびUiが両方とも参照型かつTiがUiのサブタイプさらに、キャプチャ時は、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にキャスト |
実装メソッドの引数リストとインタフェース・メソッドの引数リストはいくつかの点で異なる場合があります。実装メソッドは、ラムダ式によってキャプチャされる引数に対応するために追加引数を持つ場合があります。引数に許可された適応(キャスト、ボクシング、アンボクシング、プリミティブ・ワイドニングなど)による違いがある場合もあります。(可変引数適応はメタファクトリによって扱われません。これらは呼出し元によって扱われることが期待されます。)
invokedynamicコール・サイトには2つの引数リスト、静的引数リストと動的引数リストがあります。静的引数リストは定数プールに格納されますが、動的引数はキャプチャ時にオペランド・スタックにプッシュされます。ブートストラップ・メソッドは、静的引数リスト全体(この場合、実装メソッド、ターゲット・インタフェースおよびターゲット・インタフェース・メソッドを記述する情報を含む)、動的引数の数と静的な型(ただし値ではない)およびinvokedynamicサイトの静的な戻り型を記述するメソッド・シグネチャにアクセスできます。
| 修飾子と型 | フィールドと説明 |
|---|---|
static int |
FLAG_BRIDGES
ラムダ・オブジェクトが追加のブリッジ・メソッドを必要としていることを示す、代替メタファクトリ用のフラグ
|
static int |
FLAG_MARKERS
ラムダ・オブジェクトがSerializable以外に他のマーカー・インタフェースを実装することを示す、代替メタファクトリ用のフラグ
|
static int |
FLAG_SERIALIZABLE
ラムダ・オブジェクトが直列化可能である必要があることを示す、代替メタファクトリ用のフラグ
|
| コンストラクタと説明 |
|---|
LambdaMetafactory() |
| 修飾子と型 | メソッドと説明 |
|---|---|
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つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。 |
public static final int FLAG_SERIALIZABLE
public static final int FLAG_MARKERS
public static final int FLAG_BRIDGES
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と同じ場合、またはその特殊化の場合があります。invokedTypeで指定されるインタフェースのインスタンスを生成できるLambdaConversionException - 前述のリンケージ不変条件に違反する場合public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws LambdaConversionException
MethodHandleへの委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。一般的にinvokedynamicコール・サイトのブートストラップ・メソッドとして、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートするために使用されます。
これは一般的で、柔軟性の高いメタファクトリです。合理化されたバージョンがaltMetafactory(MethodHandles.Lookup, String, MethodType, Object...)によって提供されます。このメソッドの動作の概要はすでに説明済です。
このメソッドの引数リストには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[]配列invokedTypeで指定されるインタフェースのインスタンスを生成できるLambdaConversionException - 前述のリンケージ不変条件に違反する場合 バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.