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.