おそらく型適応と引数の部分評価の後に、指定されたMethodHandle
への委譲によって、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にするメソッド。 これらのメソッドは一般に、invokedynamic
コール・サイトのブートストラップ・メソッドとして使用され、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートします。
提供されたMethodHandle
によって指定された動作への間接アクセスは、3つのフェーズで順番に進行します。
リンケージ。このクラスのメソッドが呼び出されたときに発生します。 引数として、実装するインタフェース(通常、「機能インタフェース」は単一の抽象メソッドを持ちます)、実装するインタフェースからのメソッドの名前およびシグネチャ、そのメソッドに必要な実装動作を記述する「ダイレクト・メソッド・ハンドル」、およびその他の追加メタデータ、および適切なファンクション・オブジェクトの作成にターゲットを使用できる
CallSite
を生成します。リンクには、ターゲット・インタフェースを実装する新しいクラスを動的にロードしたり、適切な既存クラスを再利用したりすることが必要な場合があります。
CallSite
は関数オブジェクトのファクトリと見なすことができるため、これらのリンケージ・メソッドはメタファクトリと呼ばれます。キャプチャ。
CallSite
のターゲットが呼び出されるときに発生し(一般的にinvokedynamic
コール・サイトによって)、関数オブジェクトを生成します。 これは、単一ファクトリCallSite
に対して何度も発生する場合があります。動作
MethodHandle
に、指定されたインタフェース・メソッドのパラメータ以外の追加パラメータがある場合、これらは「取得されたパラメータ」と呼ばれます。これは、CallSite
ターゲットの引数として指定する必要があります。 取得されるパラメータの数およびタイプは、リンク時に決定されます。取得には、新しい関数オブジェクトの割当てが含まれることも、適切な既存の関数オブジェクトを返す場合もあります。 取得によって生成されたファンクション・オブジェクトのアイデンティティは予測不能であるため、アイデンティティに敏感な操作(参照等価、オブジェクト・ロック、
System.identityHashCode()
など)では、異なる実装、または同じ実装での異なる呼出しでさえ異なる結果になる場合があります。呼出し。実装されたインタフェース・メソッドが関数オブジェクトで呼び出されたときに発生します。 これは、単一関数オブジェクトに対して何度も発生する場合があります。 実装
MethodHandle
によって参照されるメソッドが呼び出され、取得された引数および呼出し引数に渡されます。 メソッドの結果が返されます。
呼出しで許可される入力または結果のセットを制限することが便利な場合があります。 たとえば、ジェネリック・インタフェース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
を参照してください。
リンケージ引数は次のことを前提とします。
factoryType
(CallSite
シグネチャの説明)には、タイプ(D1..Dk)および戻り型RdのKパラメータがありますinterfaceMethodType
(実装されたメソッド・タイプの説明)には、タイプ(U1..Un)および戻り型RuのNパラメータがありますimplementation
(実装を提供するMethodHandle
)には、タイプ(A1..Am)および戻り型Ra (メソッドがインスタンス・メソッドを記述する場合、このメソッド・ハンドルのメソッド・タイプには、受信側に対応する追加の第1引数がすでに含まれています)のMパラメータがありますdynamicMethodType
(起動時の制限の許可)には、タイプ(T1..Tn)および戻り型RTのNパラメータがあります。
さらに、次のリンケージ不変条件を保持する必要があります。
interfaceMethodType
とdynamicMethodType
は同じアリティ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に適応可能
また、取得時にimplementation
がインスタンス・メソッドに対応し、取得引数(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 final int
ラムダ・オブジェクトを示す代替メタ・ファクタのフラグには、implementation
を起動する追加メソッドが必要ですstatic final int
ラムダ・オブジェクトがSerializable
以外のインタフェースを実装することを示すaltMetafactory(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.Object...)
のフラグstatic final int
ラムダ・オブジェクトが直列化可能である必要があることを示すaltMetafactory(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.Object...)
のフラグ -
メソッドのサマリー
修飾子と型メソッド説明static CallSite
altMetafactory
(MethodHandles.Lookup caller, String interfaceMethodName, MethodType factoryType, Object... args) 適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。static CallSite
metafactory
(MethodHandles.Lookup caller, String interfaceMethodName, MethodType factoryType, MethodType interfaceMethodType, MethodHandle implementation, MethodType dynamicMethodType) 適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。
-
フィールド詳細
-
FLAG_SERIALIZABLE
public static final int FLAG_SERIALIZABLEラムダ・オブジェクトが直列化可能である必要があることを示すaltMetafactory(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.Object...)
のフラグ- 関連項目:
-
FLAG_MARKERS
public static final int FLAG_MARKERSラムダ・オブジェクトがSerializable
以外のインタフェースを実装することを示すaltMetafactory(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.Object...)
のフラグ- 関連項目:
-
FLAG_BRIDGES
public static final int FLAG_BRIDGESラムダ・オブジェクトを示す代替メタ・ファクタのフラグには、implementation
を起動する追加メソッドが必要です- 関連項目:
-
-
メソッドの詳細
-
metafactory
public static CallSite metafactory(MethodHandles.Lookup caller, String interfaceMethodName, MethodType factoryType, MethodType interfaceMethodType, MethodHandle implementation, MethodType dynamicMethodType) throws LambdaConversionException 適切な型適応および引数の部分評価の後、指定されたMethodHandle
への委譲により、1つ以上のインタフェースを実装する単純な関数オブジェクトの作成を容易にします。 一般的にinvokedynamic
コール・サイトのブートストラップ・メソッドとして、Javaプログラミング言語のラムダ式およびメソッド参照式機能をサポートするために使用されます。これは標準の、合理化されたメタファクトリです。
altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)
によってより高い柔軟性が提供されます。 このメソッドの動作の概要はすでに説明
済です。このメソッドから返された
CallSite
のターゲットが呼び出されると、結果として得られる関数オブジェクトは、戻り値のfactoryType
という名前のインタフェースを実装するクラスのインスタンスであり、interfaceMethodName
およびinterfaceMethodType
によって指定される名前のメソッドが宣言されます。Object
からの追加メソッドをオーバーライドすることもできます。- パラメータ:
caller
- 呼出し元のアクセス可能性権限を持つルックアップ・コンテキストを表します。 特に、参照コンテキストには「完全な権限アクセス」が必要です。invokedynamic
で使用されるときは、これはVMによって自動的にスタックされます。interfaceMethodName
- 実装メソッドの名前。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。factoryType
-CallSite
の予想されるシグネチャ。 パラメータ型はキャプチャ変数の型を表し、戻り型は実装するインタフェースです。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。interfaceMethodType
- 関数オブジェクトによって実装されるメソッドのシグネチャおよび戻り型。implementation
- 起動時に(引数の型と戻り型への適切な適応と、起動引数の前に取得された引数を使用)と呼ばれる実装メソッドを記述する直接メソッド・ハンドル。dynamicMethodType
- 起動時に動的に適用するシグネチャと戻り型。 単純なユースケースでは、これはinterfaceMethodType
と同じです。- 戻り値:
- ターゲットを使用して取得を実行し、
factoryType
という名前のインタフェースのインスタンスを生成できるCallSite - 例外:
LambdaConversionException
-caller
に完全な権限アクセス権がない場合、またはinterfaceMethodName
が有効なJVMメソッド名でない場合、またはfactoryType
の戻りタイプがインタフェースでない場合、またはimplementation
がメソッドまたはコンストラクタを参照する直接メソッド・ハンドルでない場合、または定義済のabove
のようにリンク不変者に違反している場合。NullPointerException
- 引数がnull
の場合。SecurityException
- セキュリティ・マネージャが存在し、「アクセスを拒否」がcaller
からimplementation
のパッケージである場合。
-
altMetafactory
public static CallSite altMetafactory(MethodHandles.Lookup caller, String interfaceMethodName, MethodType factoryType, 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 interfaceMethodName, MethodType factoryType, Object... args)
しかし、引数リストが以下であるかのように動作します。
CallSite altMetafactory(MethodHandles.Lookup caller, String interfaceMethodName, MethodType factoryType, MethodType interfaceMethodType, MethodHandle implementation, MethodType dynamicMethodType, int flags, int altInterfaceCount, // IF flags has MARKERS set Class... altInterfaces, // IF flags has MARKERS set int altMethodCount, // IF flags has BRIDGES set MethodType... altMethods // IF flags has BRIDGES set )
metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)
の引数リスト内の引数は、そのメソッド内と同じ仕様を持ちます。 追加引数は次のように解釈されます。flags
は追加オプションを示します。これは、必要なフラグのビット単位ORです。 定義済フラグはFLAG_BRIDGES
、FLAG_MARKERS
およびFLAG_SERIALIZABLE
です。altInterfaceCount
は、ファンクション・オブジェクトが実装する必要のある追加インタフェースの数で、FLAG_MARKERS
フラグが設定されている場合にのみ存在します。altInterfaces
は、実装する追加インタフェースの可変長リストで、長さはaltInterfaceCount
で、FLAG_MARKERS
フラグが設定されている場合にのみ存在します。altMethodCount
は、ファンクション・オブジェクトが実装する必要がある追加のメソッド・シグネチャの数で、FLAG_BRIDGES
フラグが設定されている場合にのみ存在します。altMethods
は、実装する追加メソッド・シグネチャの可変長リストで、長さはaltMethodCount
であり、FLAG_BRIDGES
フラグが設定されている場合にのみ存在します。
altInterfaces
で指定された各クラスは、above
で説明されているように、Rd
(factoryType
の戻り型)と同じ制限に従います。altMethods
で指定された各MethodType
は、above
で説明されているように、interfaceMethodType
と同じ制限に従います。flags
にFLAG_SERIALIZABLEが設定されているとき、関数オブジェクトはSerializable
を実装し、適切なSerializedLambda
を返すwriteReplace
メソッドを持ちます。caller
クラスは、SerializedLambda
で説明したとおり適切な$deserializeLambda$
メソッドを持つ必要があります。このメソッドから返される
CallSite
のターゲットが呼び出されるとき、結果の関数オブジェクトは次のプロパティを持つクラスのインスタンスです。- クラスは、
factoryType
の戻り型およびaltInterfaces
によって命名されたインタフェースを実装 - クラスは、
interfaceMethodName
で指定された名前と、interfaceMethodType
によって与えられたシグネチャ、およびaltMethods
によって指定される追加のシグネチャを含むメソッドを宣言 - このクラスは
Object
からのメソッドをオーバーライドでき、直列化に関連するメソッドを実装できます。
- パラメータ:
caller
- 呼出し元のアクセス可能性権限を持つルックアップ・コンテキストを表します。 特に、参照コンテキストには「完全な権限アクセス」が必要です。invokedynamic
で使用されるときは、これはVMによって自動的にスタックされます。interfaceMethodName
- 実装メソッドの名前。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。factoryType
-CallSite
の予想されるシグネチャ。 パラメータ型はキャプチャ変数の型を表し、戻り型は実装するインタフェースです。invokedynamic
で使用されるときは、これはInvokeDynamic
構造のNameAndType
によって提供され、VMによって自動的にスタックされます。args
- 前述のとおり、必要な引数interfaceMethodType
,implementation
,dynamicMethodType
,flags
および任意のオプションの引数を含むObject
の配列- 戻り値:
- ターゲットを使用して取得を実行し、
factoryType
という名前のインタフェースのインスタンスを生成できるCallSite - 例外:
LambdaConversionException
-caller
に完全な権限アクセス権がない場合、またはinterfaceMethodName
が有効なJVMメソッド名でない場合、またはfactoryType
の戻りタイプがインタフェースでない場合、またはaltInterfaces
のいずれかがインタフェースでない場合、またはimplementation
がメソッドまたはコンストラクタを参照する直接メソッド・ハンドルでない場合、またはabove
の定義に従ってリンク不変者に違反している場合。NullPointerException
- いずれかの引数またはargs
のコンポーネントがnull
の場合。IllegalArgumentException
-args
のコンポーネントの数またはタイプが前述のルールに従っていない場合、またはaltInterfaceCount
またはaltMethodCount
が負の整数である場合。SecurityException
- セキュリティ・マネージャが存在し、「アクセスを拒否」がcaller
からimplementation
のパッケージである場合。
-