クラスMethodHandles.Lookup
- 含まれているクラス:
MethodHandles
メソッド・ハンドルを作成する必要のあるルックアップ・クラスは、MethodHandles.lookupを呼び出して自分用のファクトリを作成します。 Lookupファクトリ・オブジェクトの作成時には、ルックアップ・クラスのアイデンティティが決定され、その情報がLookupオブジェクト内にセキュアに格納されます。 その後、ルックアップ・クラス(またはその委譲先)は、Lookupオブジェクトのファクトリ・メソッドを使ってアクセス・チェックされたメンバーのメソッド・ハンドルを作成できます。 これには、ルックアップ・クラスに許可されるメソッド、コンストラクタ、およびフィールドがすべて含まれます(privateのものも含む)。
Lookupファクトリ・メソッド
Lookupオブジェクトのファクトリ・メソッドは、メソッド、コンストラクタ、およびフィールドのすべてのメジャーなユース・ケースに対応しています。 ファクトリ・メソッドによって作成される各メソッド・ハンドルは、特定のバイトコード動作と機能的に同等です。 (バイトコードの動作は、Java Virtual Machine仕様の5.4.3.5の項で説明されています。) これらのファクトリ・メソッドと、結果として得られるメソッド・ハンドルの動作との対応の概要を以下に示します:
| ルックアップ式 | member | バイトコード動作 |
|---|---|---|
lookup.findGetter(C.class,"f",FT.class) |
FT f; | (T) this.f; |
lookup.findStaticGetter(C.class,"f",FT.class) |
staticFT f; | (FT) C.f; |
lookup.findSetter(C.class,"f",FT.class) |
FT f; | this.f = x; |
lookup.findStaticSetter(C.class,"f",FT.class) |
staticFT f; | C.f = arg; |
lookup.findVirtual(C.class,"m",MT) |
T m(A*); | (T) this.m(arg*); |
lookup.findStatic(C.class,"m",MT) |
staticT m(A*); | (T) C.m(arg*); |
lookup.findSpecial(C.class,"m",MT,this.class) |
T m(A*); | (T) super.m(arg*); |
lookup.findConstructor(C.class,MT) |
C(A*); | new C(arg*); |
lookup.unreflectGetter(aField) |
(static)?FT f; | (FT) aField.get(thisOrNull); |
lookup.unreflectSetter(aField) |
(static)?FT f; | aField.set(thisOrNull, arg); |
lookup.unreflect(aMethod) |
(static)?T m(A*); | (T) aMethod.invoke(thisOrNull, arg*); |
lookup.unreflectConstructor(aConstructor) |
C(A*); | (C) aConstructor.newInstance(arg*); |
lookup.unreflectSpecial(aMethod,this.class) |
T m(A*); | (T) super.m(arg*); |
lookup.findClass("C") |
class C { ... } | C.class; |
Cはメンバーが検索されるクラスまたはインタフェースで、ルックアップ・メソッド内でrefcという名前のパラメータとして記述されています。 メソッド型MTは、戻り型Tと引数型シーケンスA*から構成されます。 コンストラクタも引数型シーケンスA*を持ち、型Cの新しく作成されたオブジェクトを返すと見なされます。 MTとフィールドの型FTはどちらも、typeという名前のパラメータとしてドキュメント化されています。 仮パラメータthisはC型の自己参照を表しています。これは、存在する場合は常にメソッド・ハンドル呼出しの先頭の引数になります。 (一部のprotectedメンバーでは、thisの型がルックアップ・クラスに制限される場合があります。下記を参照してください。) 名前argは、メソッド・ハンドルのほかのすべての引数を表しています。 Core Reflection APIのコード例に含まれる名前thisOrNullは、アクセス対象のメソッドやフィールドがstaticの場合はnull参照を表し、それ以外の場合はthisを表します。 aMethod、aFieldおよびaConstructorの名前は、Cに宣言された特定のメンバーに対応するリフレクト・オブジェクトを表します。
findClass操作のバイトコード動作は、ldc CONSTANT_Classのように、定数クラスのロードです。 動作は、メソッド・ハンドルとしてではなく、Class定数として直接表されます。
指定されたメンバーが可変引数(つまりメソッドまたはコンストラクタ)の場合、返されるメソッド・ハンドルも可変引数になります。 その他のすべての場合、返されるメソッド・ハンドルは固定引数になります。
ディスカッション: ルックアップされたメソッド・ハンドルと基礎となるクラス・メンバーとバイトコード動作との間の等価性が、いくつかの方法で壊れることがあります。
Cがルックアップ・クラスのローダーからシンボルでアクセスできない場合でも、ルックアップが成功することがあります(同等のJava式やバイト・コード定数が存在しない場合でも)。- 同様に、
TまたはMTがルックアップ・クラスのローダーからシンボルでアクセスできない場合でも、ルックアップが成功することがあります。 たとえば、MethodHandle.invokeExactやMethodHandle.invokeのルックアップは、要求された型とは無関係に常に成功します。 - 参照されたメソッドに「非常に多い引数」がある場合、メソッド・ハンドルの作成は
IllegalArgumentExceptionで失敗することがあります。これは、メソッド・ハンドルの型が「あまりにも多くのパラメータ」を持つためです。
アクセス・チェック
アクセス・チェックは、メソッド・ハンドルの作成時にLookupのファクトリ・メソッド内で適用されます。 これが、Core Reflection APIとの重要な違いです(java.lang.reflect.Method.invokeではすべての呼出しで、すべての呼出し元に対してアクセス・チェックが実行される)。
すべてのアクセス・チェックはLookupオブジェクトから始まりますが、このオブジェクトでは、記録されているルックアップ・クラスとすべてのメソッド・ハンドル作成要求とが照合されます。 単一のLookupオブジェクトを使って任意の数のアクセス・チェック済みメソッド・ハンドルを作成できます(すべては単一のルックアップ・クラスに基づいてチェックされる)。
Lookupオブジェクトは、ほかの信頼できるコード(メタオブジェクト・プロトコルなど)と共有できます。 共有Lookupオブジェクトは、メソッド・ハンドルを作成する機能を、ルックアップ・クラスのprivateメンバーに委譲します。 特権付きコードがLookupオブジェクトを使用する場合でも、アクセス・チェックは元のルックアップ・クラスの特権に限定されます。
ルックアップが失敗することがあります。包含するクラスにルックアップ・クラスからアクセスできない、目的のクラス・メンバーが見つからない、目的のクラス・メンバーにルックアップ・クラスからアクセスできない、またはルックアップ・オブジェクトが信頼されていないためメンバーにアクセスためです。 finalフィールドに対するフィールドのsetter関数の場合、finalityは、アクセス制御の一種として扱われ、Lookup.unreflectSetterの特別なケースを除いてルックアップは失敗します。 いずれの場合も、試みられたルックアップからReflectiveOperationExceptionがスローされます。 具体的なクラスは次のいずれかになります。
- NoSuchMethodException-要求されたメソッドが存在しない場合
- NoSuchFieldException-要求されたフィールドが存在しない場合
- IllegalAccessException-メンバーは存在しているが、アクセス・チェックが失敗した場合
一般に、メソッドMがメソッド・ハンドルをルックアップできる条件は、ルックアップ・クラスがMへの呼出しをコンパイル、検証、解決できる条件ほど制限的ではありません。 JVMがNoSuchMethodErrorなどの例外をスローするとき、メソッド・ハンドル・ルックアップは一般にNoSuchMethodExceptionなどの対応するチェック例外をスローします。 また、ルックアップの結果実行されるメソッド・ハンドル呼出しの効果は、コンパイル、検証および解決されたM呼出しを実行するのとまったく同じです。 フィールドとコンストラクタについても同じことが言えます。
ディスカッション: アクセス・チェックは、名前付きのリフレクトされたメソッド、コンストラクタ、およびフィールドにのみ適用されます。 MethodHandle.asTypeなど、他のメソッド・ハンドル作成メソッドは、アクセス・チェックを必要とせず、Lookupオブジェクトから独立して使用されます。
目的のメンバーがprotectedの場合は、通常のJVMルールが適用されます。たとえば、ルックアップ・クラスが目的のメンバーと同じパッケージ内に存在する必要があるという要件や、そのメンバーを継承する必要があります。 (Java Virtual Machine仕様の4.9.2、5.4.3.5および6.4の項を参照してください。) また、目的のメンバーが別のパッケージ内にある非staticフィールドまたはメソッドである場合、結果となるメソッド・ハンドルはルックアップ・クラスまたはそのいずれかのサブクラスのオブジェクトにしか適用されない可能性があります。 この要件は、先頭のthisパラメータの型をC (必ずルックアップ・クラスのスーパー・クラスになる)からルックアップ・クラス自体にナロー変換することで強制されます。
JVMは同様の要件をinvokespecial命令に適用します(レシーバ引数が解決済メソッドおよび現在のクラスに一致する必要がある)。 さらにこの要件は、先頭パラメータの型を結果のメソッド・ハンドルにナロー変換することで適用されます。 (Java Virtual Machine仕様の4.10.1.9の項を参照してください。)
JVMは、特殊な名前("<init>"と"<clinit>")を持つ内部メソッドとして、コンストラクタおよび静的イニシャライザ・ブロックを表します。 呼出し命令の内部構文は、そのような内部メソッドを通常のメソッドのように参照することを許可しますが、JVMバイトコード・ベリファイアはそれらを拒否します。 そのような内部メソッドをルックアップはNoSuchMethodExceptionを生成します。
ネストされた型間の関係がNestHost属性とNestMembers属性(Java Virtual Machine仕様の4.7.28および4.7.29の項を参照してください。)を介して直接表現される場合、関連付けられたLookupオブジェクトは、ルックアップ・クラスとそのすべてのネストされた(Class.getNestHostを参照してください)への直接アクセスを提供します。 それ以外の場合、ネストされたクラス間のアクセスは、同じネスト内の別のクラスのprivateメソッドにアクセスするラッパー・メソッドを作成するJavaコンパイラによって取得されます。 たとえば、ネストされたクラスC.Dはほかの関連クラス(C、C.D.E、C.Bなど)の内部のprivateメンバーにアクセスできますが、Javaコンパイラがそれらの関連クラス内でラッパー・メソッドを生成しなければいけない可能性があります。 このような場合、C.E上のLookupオブジェクトはそのプライベート・メンバーにアクセスできません。 この制限の回避策は、Lookup.inメソッドです。このメソッドでは、C.Eに対するルックアップを他のクラスのいずれかに変換でき、特別な権限は付与されません。
指定されたルックアップ・オフセットに許可されるアクセスは、そのlookupModesセットに基づいて、ルックアップ・クラスから通常アクセスできるメンバー・サブセットに制限される場合があります。 たとえば、publicLookupメソッドは、エクスポートされたパッケージのパブリック・クラスのパブリック・メンバーへのアクセスのみを許可されるルックアップ・オブジェクトを生成します。 呼出し元依存メソッドlookupは、サポートされているすべてのバイトコード動作をエミュレートする、呼出し元クラスに関連するあらゆる機能を持つルックアップ・オブジェクトを生成します。 また、Lookup.inメソッドは元のルックアップ・オブジェクトよりアクセス・モードが少ないルックアップ・オブジェクトを生成できます。
プライベート・アクセスとモジュール・アクセスについての説明:そのルックアップ・モードがprivateメンバー(ネストのプライベート・メンバーを含む)へのアクセスの可能性が含まれていると、参照にはプライベート・アクセスがあると呼びます。 ドキュメント内の関連メソッドに記述されているように、privateアクセスを持つルックアップのみが次の機能を持ちます。
- ルックアップ・クラスおよびそのネスト元のプライベート・フィールド、メソッドおよびコンストラクタへのアクセス
invokespecial命令をエミュレートするメソッド・ハンドルを作成する- 同じパッケージ・メンバー内の他のクラスに対するprivateアクセスを持つ、
委譲されたルックアップ・オブジェクトを作成する
同様に、モジュール・アクセスを持つ参照では、元の参照作成者が参照クラスと同じモジュール内のメンバーであることが保証されます。
プライベートおよびモジュールへのアクセスは、独立して決定されるモードであり、参照には両方、またはどちらもない可能性があります。 両方のアクセス・モードを持つ参照は、「完全な権限アクセス」と言われます。
「元のアクセス」を使用したルックアップでは、このルックアップが元のルックアップ・クラスによって作成され、ブートストラップ・メソッドがVMによって呼び出されることが保証されます。 元のアクセス権を持つこのようなルックアップには、次の追加機能を持つプライベートおよびモジュール・アクセス権もあります:
これらのことが許可されるのは、privateアクセスを持つルックアップ・オブジェクトから元のクラスまで安全にたどることができ、そのバイトコード動作およびJava言語アクセス権をメソッド・ハンドルが確実に判断してエミュレートできるという事実の結果です。
モジュール間参照
あるモジュールM1の参照クラスが別のモジュールM2にあるクラスにアクセスする場合、アクセス・モード・ビットの範囲を超えて余分なアクセス・チェックが実行されます。 PUBLICモードのLookupおよびM1の参照クラスでは、M2がM1に対して読取り可能である場合、およびタイプがM1以上にエクスポートされるM2のパッケージ内にある場合、M2のパブリック・タイプにアクセスできます。
C上のLookupでは、Lookup.inおよびMethodHandles.privateLookupInメソッドを介してターゲット・クラスに「テレ・ポート」を実行することもできます。 モジュール間でのポートレット化では、「前のルックアップ・クラス」として元の参照クラスが常に記録され、MODULEアクセス権が削除されます。 ターゲット・クラスがルックアップ・クラスCと同じモジュール内にある場合、そのターゲット・クラスは新しいルックアップ・クラスになり、以前のルックアップ・クラスに変更はありません。 ターゲット・クラスがM1 (Cのモジュール)とは異なるモジュールにある場合は、Cが新しい以前の参照クラスになり、ターゲット・クラスが新しい参照クラスになります。 その場合、M0に以前のルックアップ・クラスがすでに存在し、M1とM2と異なる場合は、結果のルックアップがすべての権限をドロップします。 たとえば、
Lookup lookup = MethodHandles.lookup(); // in class C
Lookup lookup2 = lookup.in(D.class);
MethodHandle mh = lookup2.findStatic(E.class, "m", MT);
MethodHandles.lookup()ファクトリ・メソッドにより、nullの前のルックアップ・クラスを持つLookupオブジェクトが生成されます。lookup.in(D.class)は、クラスCのlookupを、権限を昇格させずにDクラスに変換します。 CとDが同じモジュールの場合、lookup2はDを新しい参照クラスとして記録し、元のlookupと同じ前の参照クラスを維持します。存在しない場合は、nullになります。
あるネストされたクラスから別のネストされたクラスへのLookupテレ・ポートを実行すると、PRIVATEアクセス権が削除されます。 あるパッケージのクラスから別のパッケージへのLookupテレ・ポートを実行すると、PACKAGEにアクセスできなくなります。 あるモジュールのクラスから別のモジュールへのLookupポートが提供されると、MODULEアクセス権が切断されます。 モジュール間のテレティングでは、新しいルックアップ・クラスのモジュールと古いルックアップ・クラスのモジュールの両方から、エクスポートされていないクラスにアクセスする機能をドロップします。そうすると、LookupではPUBLICアクセスのみが可能になります。 Lookupは、参照クラスのモジュール内のクラスおよび前のクラス参照のモジュールに電話をかけて移動できます。 モジュール間の通信は、アクセス権を減らすことのみができますが、増やすことはできません。 3つ目のモジュールに通信している場合は、すべてのアクセスを削除します。
前述の例では、CとDが異なるモジュールにある場合、lookup2はDをその参照クラスとして記録し、lookup2にはPUBLICアクセスのみがあります。lookup2は、C 'モジュールおよびD'モジュールの他のクラスへの通信を行えます。 Eクラスが3番目のモジュールにある場合、lookup2.in(E.class)はアクセスなしでEにLookupを作成し、lookup2の参照クラスDは以前の参照クラスとして記録されます。
モジュール間の通信によって、参照クラスと前の参照クラスの両方が(下記参照)に同等にアクセスできるパブリック・タイプにアクセスが制限されます。
MethodHandles.privateLookupIn(T.class, lookup)を使用すると、クラスCからクラスTにlookupをテレポートし、ルックアップ・クラスでTに対して「深い反射」を実行できる場合は、「プライベート・アクセス」を使用して新しいLookupを生成できます。 lookupでprivateLookupInをコールするには、MODULEおよびPRIVATEアクセス権が必要です。 モジュールM1のC上でのlookupは、M1内のすべてのクラスに対してディープ・リフレクションを実行できます。 TがM1に含まれる場合、privateLookupInでは、完全な機能を備えたT上に新しいLookupが生成されます。 Cでのlookupは、M1がM2、M2 opensにM1を含むパッケージを読み取る場合に、別のモジュールM2でTをさらに深くリフレクションすることもできます。 T が新しい参照クラスになり、Cが新しい以前の参照クラスになり、MODULEのアクセス権が結果のLookupから削除されます。 結果のLookupを使用すると、Lookup::inをコールして、別の参照クラスにメンバー参照またはテレ・ポートを実行できます。 ただし、MODULEアクセス権がないため、privateLookupInをコールして別のプライベートLookupを取得するためには使用できません。
privateLookupInによって返されるLookupオブジェクトは、Tの実行時パッケージで「クラスの定義」に許可されます。 パッケージを別のモジュールに開く場合は、M2内のほかのメンバーと同じ完全なアクセス権を持つように、特に注意してください。
モジュール間アクセス・チェック
PUBLICを含むLookupまたはUNCONDITIONALモードを使用すると、モジュール間アクセスが可能になります。 アクセス・チェックは、参照クラスと前の参照クラス(存在する場合)の両方に対して実行されます。
UNCONDITIONALモードのLookupでは、すべてのモジュールのパブリック・タイプは「無条件でエクスポート」のパッケージの中にアクセスできます。
M1のLCのLookupに以前の参照クラスがない場合、PUBLICモードで参照すると、M1で読取り可能なモジュール内のすべてのパブリック・タイプにアクセスでき、タイプは少なくともM1にエクスポートされるパッケージ内にあります。
M1のLCのLCに以前の参照クラスM0の前の参照クラスPLCがある場合、PUBLICモードでの参照は、PUBLICモードで参照すると、M0からアクセス可能なすべてのパブリック・タイプを使用して、M1でアクセスできるすべてのパブリック・タイプの共通部分にアクセスできます。 M0 はM1を読み取るため、アクセス可能なタイプのセットには次のものがあります:
M1からの無条件エクスポートのパッケージM1がM0を読み込む場合、M0から無条件エクスポート・パッケージをエクスポート-
M0とM1の両方がM2を読み上げた場合、第3のモジュールM2から無条件エクスポートのパッケージをエクスポート - レイヤー化されたエクスポート済パッケージ:
M1からM0へ M1がM0を読み取った場合に、M0からM1に並列エクスポートされたパッケージ-
M0とM1の両方がM2を読む場合、3番目のモジュールM2からM0とM1の両方にレイヤー化されたエクスポートされたパッケージ
アクセス・モード
次の表に、ファクトリまたは変換のいずれかのメソッドによって生成されるLookupのアクセス・モードを示します:
MethodHandles::lookupMethodHandles::publicLookupMethodHandles::privateLookupInLookup::inLookup::dropLookupMode
| オブジェクトの参照 | オリジナル | protected | private | package | module | public |
|---|---|---|---|---|---|---|
CのCL = MethodHandles.lookup() |
ORI | PRO | PRI | PAC | MOD | 1R |
CL.in(C1)同じパッケージ |
PAC | MOD | 1R | |||
CL.in(C1)同じモジュール |
MOD | 1R | ||||
CL.in(D)異なるモジュール |
2R | |||||
モジュールにCL.in(D).in(C)ホップ・バック |
2R | |||||
PRI1 = privateLookupIn(C1,CL) |
PRO | PRI | PAC | MOD | 1R | |
PRI1a = privateLookupIn(C,PRI1) |
PRO | PRI | PAC | MOD | 1R | |
PRI1.in(C1)同じパッケージ |
PAC | MOD | 1R | |||
PRI1.in(C1)異なるパッケージ |
MOD | 1R | ||||
PRI1.in(D)異なるモジュール |
2R | |||||
PRI1.dropLookupMode(PROTECTED) |
PRI | PAC | MOD | 1R | ||
PRI1.dropLookupMode(PRIVATE) |
PAC | MOD | 1R | |||
PRI1.dropLookupMode(PACKAGE) |
MOD | 1R | ||||
PRI1.dropLookupMode(MODULE) |
1R | |||||
PRI1.dropLookupMode(PUBLIC) |
none | |||||
PRI2 = privateLookupIn(D,CL) |
PRO | PRI | PAC | 2R | ||
privateLookupIn(D,PRI1) |
PRO | PRI | PAC | 2R | ||
privateLookupIn(C,PRI2)は失敗 |
IAE | |||||
PRI2.in(D2)同じパッケージ |
PAC | 2R | ||||
PRI2.in(D2)異なるパッケージ |
2R | |||||
モジュールにPRI2.in(C1)ホップ・バック |
2R | |||||
PRI2.in(E)ホップから3番目のモジュール |
none | |||||
PRI2.dropLookupMode(PROTECTED) |
PRI | PAC | 2R | |||
PRI2.dropLookupMode(PRIVATE) |
PAC | 2R | ||||
PRI2.dropLookupMode(PACKAGE) |
2R | |||||
PRI2.dropLookupMode(MODULE) |
2R | |||||
PRI2.dropLookupMode(PUBLIC) |
none | |||||
CL.dropLookupMode(PROTECTED) |
PRI | PAC | MOD | 1R | ||
CL.dropLookupMode(PRIVATE) |
PAC | MOD | 1R | |||
CL.dropLookupMode(PACKAGE) |
MOD | 1R | ||||
CL.dropLookupMode(MODULE) |
1R | |||||
CL.dropLookupMode(PUBLIC) |
none | |||||
PUB = publicLookup() |
U | |||||
PUB.in(D)異なるモジュール |
U | |||||
PUB.in(D).in(E) 3番目のモジュール |
U | |||||
PUB.dropLookupMode(UNCONDITIONAL) |
none | |||||
privateLookupIn(C1,PUB)は失敗 |
IAE | |||||
ANY.in(X)(アクセスできないXの場合) |
none |
ノート:
CクラスとC1クラスは、モジュールM1内にありますが、DとD2はモジュールM2で、EはモジュールM3にあります。Xは、参照がアクセス不可能なクラスを探します。ANYは、サンプル・ルックアップの表します。ORIはORIGINALビット・セットを示し、PROはPROTECTEDビット・セットを示し、PRIはPRIVATEビット・セットを示し、PACはPACKAGEビット・セットを示し、MODはMODULEビット・セットを示し、1Rと2RはPUBLICコード・セットを示し、UはUNCONDITIONALビット・セットを示し、IAEはスローされたIllegalAccessExceptionを示します。- パブリック・アクセスには、次の3種類があります:
- 無条件(
U): ルックアップは読みやすくなっています。 ルックアップにnull前のルックアップ・クラスがある場合。 - one-module-reads (
1R): モジュール・アクセス・チェックは、参照クラスに対して実行します。 ルックアップにnull前のルックアップ・クラスがある場合。 - two-module-reads (
2R): モジュール・アクセス・チェックは、参照クラスおよび前の参照クラスについて実行されます。 ルックアップに、現在のルックアップ・クラスとは異なるモジュール内にあるnull以外の前のルックアップ・クラスが含まれています。
- 無条件(
- 3つ目のモジュールに到達しようとすると、すべてのアクセスが失われます。
Lookup::inでは、ターゲット・クラスXにアクセスできない場合、すべてのアクセス・モードが削除されます。
呼出し元依存メソッド
少数のJavaメソッドに、呼出し元依存性という特殊なプロパティがあります。 呼出し元依存メソッドは、その直接の呼出し元の識別情報によって異なる動作をする可能性があります。呼出し元依存メソッドのメソッド・ハンドルが要求された場合は、バイトコード動作の一般ルールが適用されますが、ルックアップ・クラスは特別な方法で考慮されます。 結果のメソッド・ハンドルはルックアップ・クラスに含まれている命令から呼び出されたように動作し、呼出し元依存メソッドはルックアップ・クラスを検出します。 (一方、メソッド・ハンドルのインボーカは無視されます。) したがって、呼出し元依存メソッドの場合は、ルックアップ・クラスごとにメソッド・ハンドルの動作が異なる可能性があります。
ルックアップ・オブジェクトがpublicLookup()の場合や、「元のアクセス」を使用しないその他のルックアップ・オブジェクトの場合は、ルックアップ・クラスが無視されます。 そのような場合、呼出し元依存メソッド・ハンドルを作成できず、アクセスは禁止され、ルックアップはIllegalAccessExceptionで失敗します。
ディスカッション: たとえば、呼出し元依存メソッドClass.forName(x)は、それを呼び出すクラスのクラス・ローダーに応じて、返されるクラスを異なったり、スローされる例外が異なったりする可能性があります。 Class.forNameのpublicルックアップは失敗します。そのバイトコード動作を判別するための妥当な方法がないためです。
広範囲な共有のためにメソッド・ハンドルをキャッシュするアプリケーションの場合は、publicLookup()を使用してメソッド・ハンドルを作成することをお薦めします。 Class.forNameのルックアップがある場合、それは失敗し、アプリケーションはその場合に適切なアクションを取る必要があります。 たとえば、後のルックアップ(おそらくブートストラップ・メソッドの呼び出し中)が呼出し元固有の識別情報を組み込むことで、メソッドをアクセス可能にするアクションです。
関数MethodHandles.lookupは呼出し元依存なので、ルックアップ用の安全な基盤が存在できます。 JSR 292 API内の他のほとんどすべてのメソッドはルックアップ・オブジェクトに依存してアクセス要求をチェックします。
- 導入されたバージョン:
- 1.7
-
ネストされたクラスのサマリー
ネストされたクラス修飾子と型クラス説明static enumLookup::defineHiddenClassメソッドによって作成された非表示クラスをルックアップ・クラスのネストに新しいメンバーとして動的に追加するかどうか、または非表示クラスがその定義ローダーとしてマークされたクラス・ローダーと強力な関係を持つかどうか(あるいはその両方)を指定するクラス・オプションのセット。 -
フィールドのサマリー
フィールド修飾子と型フィールド説明static final intmoduleのアクセスを表すシングルトン・マスクで、lookupModesの結果に影響する可能性があります。static final intoriginalアクセスを表す1ビット・マスクで、lookupModesの結果に寄与する可能性があります。static final intpackageアクセス(デフォルト・アクセス)を表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。static final intprivateアクセスを表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。static final intprotectedアクセスを表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。static final intpublicアクセスを表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。static final intunconditionalアクセスを表す1ビット・マスクで、lookupModesの結果に寄与する可能性があります。 -
メソッドのサマリー
修飾子と型メソッド説明<T> Class<T> accessClass(Class<T> targetClass) このLookupオブジェクトで定義されたルックアップ・コンテキストからクラスにアクセスできるかどうかを決定します。bind(Object receiver, String name, MethodType type) 非staticメソッドの早期バインド・メソッド・ハンドルを生成します。Class<?> defineClass(byte[] bytes) ClassLoader::defineClassをコールする場合と同様に、このルックアップ「ルックアップ・クラス」と同じクラス・ローダー、同じランタイム・パッケージおよび「保護ドメイン」で、bytesからクラスまたはインタフェースを作成してリンクします。defineHiddenClass(byte[] bytes, boolean initialize, MethodHandles.Lookup.ClassOption... options) bytesからhiddenクラスまたはインタフェースを作成し、新しく作成されたクラスまたはインタフェースにLookupを返します。defineHiddenClassWithClassData(byte[] bytes, Object classData, boolean initialize, MethodHandles.Lookup.ClassOption... options) 関連付けられた「クラス・データ」を使用してbytesからhiddenクラスまたはインタフェースを作成し、新しく作成されたクラスまたはインタフェースでLookupを返します。dropLookupMode(int modeToDrop) このルックアップ・オブジェクトがメンバーを検索する同じルックアップ・クラスに、指定されたルックアップ・モードを失ったルックアップ・モードを使用してルックアップを作成します。<T> Class<T> ensureInitialized(Class<T> targetClass) targetClassが初期化されていることを確認します。Class<?> このLookupオブジェクト「解決された場合」によってldcの命令で定義された参照コンテキストから名前でクラスを検索します。findConstructor(Class<?> refc, MethodType type) 指定された型のコンストラクタを使ってオブジェクトの作成と初期化を行うメソッド・ハンドルを生成します。findGetter(Class<?> refc, String name, Class<?> type) 非staticフィールドに対する読取りアクセスを提供するメソッド・ハンドルを生成します。findSetter(Class<?> refc, String name, Class<?> type) 非staticフィールドに対する書込みアクセスを提供するメソッド・ハンドルを生成します。findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) 仮想メソッドの早期にバインドされるメソッド・ハンドルを生成します。findStatic(Class<?> refc, String name, MethodType type) staticメソッドのメソッド・ハンドルを生成します。findStaticGetter(Class<?> refc, String name, Class<?> type) staticフィールドに対する読取りアクセスを提供するメソッド・ハンドルを生成します。findStaticSetter(Class<?> refc, String name, Class<?> type) staticフィールドに対する書込みアクセスを提供するメソッド・ハンドルを生成します。findStaticVarHandle(Class<?> decl, String name, Class<?> type) 型declのクラスで宣言された型typeの静的フィールドnameへのアクセスを提供するVarHandleを生成します。findVarHandle(Class<?> recv, String name, Class<?> type) 型recvのクラスで宣言された型typeの非静的フィールドnameへのアクセスを提供するVarHandleを生成します。findVirtual(Class<?> refc, String name, MethodType type) 仮想メソッドのメソッド・ハンドルを生成します。booleanこの参照に「完全な権限アクセス」がある場合、つまりtrueを返します。boolean非推奨。指定された新しいルックアップ・クラスでルックアップを作成します。Class<?> ルックアップを実行しているクラスを示します。intこのルックアップ・オブジェクトがどのアクセス保護クラスのメンバーを生成できるかを示します。Class<?> この参照オブジェクトが以前に電話をかけていた別のモジュール、またはnullで参照区分を報告します。revealDirect(MethodHandle target) この参照オブジェクトまたは類似のオブジェクトによって作成された直接メソッド・ハンドルを解読します。toString()ルックアップを行うクラスの名前、"/"および「前のルックアップ・クラス」の名前(存在する場合)が表示されます。ルックアップ・クラスがアクセス権を持つ場合に、mへの直接メソッド・ハンドルを作成します。リフレクトされたコンストラクタのメソッド・ハンドルを生成します。リフレクトされたフィールドに対する読取りアクセス権を提供するメソッド・ハンドルを生成します。リフレクトされたフィールドに対する書込みアクセス権を提供するメソッド・ハンドルを生成します。unreflectSpecial(Method m, Class<?> specialCaller) リフレクトされたメソッドのメソッド・ハンドルを生成します。クラスRで宣言されたT型の反映されたフィールドfへのアクセスを提供するVarHandleを生成します。
-
フィールド詳細
-
PUBLIC
public static final int PUBLICpublicアクセスを表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。 値0x01はたまたま、public修飾子ビットの値と同じになっています。この参照モードの
Lookupでは、「ルックアップ・クラス」および「前のルックアップ・クラス」(存在する場合)について、モジュール間アクセス・チェックが実行されます。- 関連項目:
-
PRIVATE
public static final int PRIVATEprivateアクセスを表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。 値0x02はたまたま、private修飾子ビットの値と同じになっています。- 関連項目:
-
PROTECTED
public static final int PROTECTEDprotectedアクセスを表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。 値0x04はたまたま、protected修飾子ビットの値と同じになっています。- 関連項目:
-
PACKAGE
public static final int PACKAGEpackageアクセス(デフォルト・アクセス)を表す単一ビット・マスク(lookupModesの結果に寄与する可能性がある)。 値は0x08ですが、これは、特定のどの修飾子ビットにも、意味のあるかたちでは対応しません。- 関連項目:
-
MODULE
public static final int MODULEmoduleのアクセスを表すシングルトン・マスクで、lookupModesの結果に影響する可能性があります。 値は0x10です。これは特定の「修飾子ビット」には意味がありません。PUBLIC修飾子ビットとともに、このルックアップ・モードのLookupは、ルックアップ・クラスのモジュール内のすべてのパブリック・タイプと、他のモジュールによってルックアップ・クラスのモジュールにエクスポートされるパッケージのパブリック・タイプにアクセスできます。この参照モードが設定されている場合、「前のルックアップ・クラス」は常に
nullです。- 導入されたバージョン:
- 9
- 関連項目:
-
UNCONDITIONAL
public static final int UNCONDITIONALunconditionalアクセスを表す1ビット・マスクで、lookupModesの結果に寄与する可能性があります。 値は0x20です。これは特定の「修飾子ビット」には意味がありません。 このルックアップ・モードのLookupはreadabilityを想定しています。 この参照モードでは、タイプがexported unconditionallyであるパッケージ内にある場合、すべてのモジュールのパブリック・タイプのすべてのパブリック・メンバーにアクセスできます。この参照モードが設定されている場合、「前のルックアップ・クラス」は常に
nullです。- 導入されたバージョン:
- 9
- 関連項目:
-
ORIGINAL
public static final int ORIGINALoriginalアクセスを表す1ビット・マスクで、lookupModesの結果に寄与する可能性があります。 値は0x40です。これは特定の「修飾子ビット」には意味がありません。このルックアップ・モードが設定されている場合、
Lookupオブジェクトは、MethodHandles.lookup()メソッドをコールするか、VMによって起動されるブートストラップ・メソッドによって、元のルックアップ・クラスによって作成される必要があります。 このルックアップ・モードのLookupオブジェクトには、「完全な権限アクセス」があります。- 導入されたバージョン:
- 16
- 関連項目:
-
-
メソッドの詳細
-
lookupClass
public Class<?> lookupClass()ルックアップを実行しているクラスを示します。 可視性やアクセス権のチェックが実行されるのは、このクラスに対してです。この参照オブジェクトに「前のルックアップ・クラス」がある場合、アクセス・チェックは参照クラスおよび前の参照クラスの両方に対して実行されます。
このクラスは最大レベルのアクセス権を暗黙的に示しますが、非publicメンバーにアクセスできるかどうかを制御するビット・マスク
lookupModesにより、アクセス権がさらに制限される可能性もあります。- 戻り値:
- ルックアップ・クラス、これのためにこのルックアップ・オブジェクトはメンバーを探す
- 関連項目:
-
previousLookupClass
public Class<?> previousLookupClass()この参照オブジェクトが以前に電話をかけていた別のモジュール、またはnullで参照区分を報告します。ファクトリ・メソッドで生成される
lookup()やpublicLookup()メソッドなどのLookupオブジェクトには、nullの前の参照クラスがあります。Lookupオブジェクトにnull以外の以前の参照クラスがあります。この参照が、あるモジュールの古い参照クラスから別のモジュールの新しい参照クラスに移植されたときです。- 戻り値:
- この参照オブジェクトが以前に通信したことのある他のモジュール内の参照クラスまたは
null - 導入されたバージョン:
- 14
- 関連項目:
-
lookupModes
public int lookupModes()このルックアップ・オブジェクトがどのアクセス保護クラスのメンバーを生成できるかを示します。 その結果、ビットPUBLIC (0x01)、「プライベート(0x02)」、「保護された(0x04)」、「パッケージ(0x08)」、MODULE (0x10)、UNCONDITIONAL (0x20)およびORIGINAL (0x40)のビット・マスクになります。「通話者のクラス」上に新しく作成されたルックアップ・オブジェクトには、
UNCONDITIONALを除くすべてのビットが設定されます。 以前のルックアップ・オブジェクトから作成された新しいルックアップ・クラス上のルックアップ・オブジェクトでは、いくつかのモード・ビットがゼロに設定されている可能性があります。 モード・ビットは「直接クリアされた」でもかまいません。 クリアすると、ダウングレードされたルックアップ・オブジェクトからモード・ビットをリストアできません。 その目的は、新しいルックアップ・オブジェクト経由でのアクセスを制限し、元のルックアップ・オブジェクトと新しいルックアップ・クラスの両方から到達可能な名前だけにアクセスできるようにすることです。- 戻り値:
- ルックアップ・モード、このルックアップ・オブジェクトによって実行されるアクセスの種類を制限する
- 関連項目:
-
in
public MethodHandles.Lookup in(Class<?> requestedLookupClass) 指定された新しいルックアップ・クラスでルックアップを作成します。 結果となるオブジェクトは、指定されたクラスを自身のlookupClassとして報告します。ただし、結果となる
Lookupオブジェクトは、元のオブジェクトと同等以下のアクセス機能しか持たないことが保証されます。 具体的には、アクセス機能が次のように失われる可能性があります。- 新しいルックアップ・クラスが古いルックアップ・クラスと異なる場合、つまり
ORIGINALアクセスが失われた場合。 - 新しいルックアップ・クラスが古いクラスとは別のモジュールにある場合、つまり
MODULEアクセスが失われる場合。 - 新しいルックアップ・クラスが古い保護されているパッケージとは異なるパッケージにある場合、およびデフォルトの(package)メンバーにはアクセスできません。つまり、
PROTECTEDおよびPACKAGEアクセスは失われます。 - 新しいルックアップ・クラスが古いルックアップ・メンバーと同じパッケージ・メンバー内にない場合、プライベート・メンバーにはアクセスできず、保護されたメンバーは継承によってアクセスできません。つまり、
PRIVATEのアクセスが失われます。 (パッケージ共有のため、protectedメンバーに引き続きアクセスできる場合もあります。) - 新しい参照クラスがこの参照に対して「アクセシビリティ」ではない場合、パブリック・メンバーでなく、すべてのアクセス・モードが失われるなど、メンバーにアクセスすることはできません。
- 新規参照クラスの場合、古い参照クラスと以前の参照クラスはすべて異なるモジュールにあります。つまり、3番目のモジュールに対するテレ・ポートでは、すべてのアクセス・モードが失われます。
以前の新規ルックアップ・クラスは次のように選択されます:
- 新しい参照オブジェクトに
UNCONDITIONALビットがある場合、以前の新しい参照クラスはnullです。 - 新しい参照クラスが古い参照クラスと同じモジュールにある場合、以前の新しい参照クラスは以前の古い参照クラスになります。
- 新しい参照クラスが古い参照クラスと異なるモジュールにある場合、新しい以前の参照クラスは古い参照クラスとなります。
クラス(
findClass(java.lang.String)呼び出し中に使用される)をロードするための結果のルックアップ機能は、ルックアップ・クラスのローダーによって決定され、この操作によって変更される可能性があります。- パラメータ:
requestedLookupClass- 新しいルックアップ・オブジェクト用に要求されるルックアップ・クラス- 戻り値:
- 必要なルックアップ・クラスをレポートするルックアップ・オブジェクト、または変更がない場合は同じオブジェクト
- スロー:
IllegalArgumentException-requestedLookupClassがプリミティブ・タイプ、voidまたは配列クラスの場合NullPointerException- 引数がnullの場合- 関連項目:
- 新しいルックアップ・クラスが古いルックアップ・クラスと異なる場合、つまり
-
dropLookupMode
public MethodHandles.Lookup dropLookupMode(int modeToDrop) このルックアップ・オブジェクトがメンバーを検索する同じルックアップ・クラスに、指定されたルックアップ・モードを失ったルックアップ・モードを使用してルックアップを作成します。 削除するルックアップ・モードは、PUBLIC、MODULE、PACKAGE、PROTECTED、PRIVATE、ORIGINALまたはUNCONDITIONALのいずれかです。このルックアップが「パブリック・ルックアップ」の場合、このルックアップには
UNCONDITIONALモードが設定され、他のモードは設定されていません。 パブリック・ルックアップにUNCONDITIONALをドロップすると、結果のルックアップにアクセスできなくなります。このルックアップがパブリック・ルックアップでない場合、「ルックアップ・モード」に関係なく次のことが適用されます。
PROTECTEDおよびORIGINALは常に削除されるため、結果として得られるルックアップ・モードにはこれらのアクセス機能はありません。PACKAGEを削除すると、結果のルックアップにはPACKAGEまたはPRIVATEアクセス権がありません。MODULEを削除すると、結果として得られるルックアップにはMODULE、PACKAGEまたはPRIVATEアクセス権がありません。PUBLICを削除すると、結果のルックアップにアクセスできなくなります。- APIのノート:
PRIVATEモードではなくPACKAGEを参照すると、「プライベート・アクセス」を提供せずに、参照クラスのパッケージ内でパブリックでないアクセスを安全に委任できます。PACKAGEモードではなくMODULEを参照すると、パッケージ・アクセス権を付与せずに、参照クラスのモジュール内でPUBLICアクセスを安全に委任できます。 「前のルックアップ・クラス」 (およびPUBLIC。MODULEモードではありません)を使用した参照では、参照クラスのモジュールと以前の参照クラスのモジュールの両方からアクセス可能なパブリック・クラスに安全にアクセス権を委任できます。- パラメータ:
modeToDrop- ルックアップ・モードをドロップ- 戻り値:
- 指定されたモードがないルックアップ・オブジェクト、または変更がない場合は同じオブジェクト
- スロー:
IllegalArgumentException-modeToDropがPUBLIC,MODULE,PACKAGE,PROTECTED,PRIVATE,ORIGINALまたはUNCONDITIONALのいずれでもない場合- 導入されたバージョン:
- 9
- 関連項目:
-
defineClass
public Class<?> defineClass(byte[] bytes) throws IllegalAccessException ClassLoader::defineClassをコールする場合と同様に、このルックアップ「ルックアップ・クラス」と同じクラス・ローダー、同じランタイム・パッケージおよび「保護ドメイン」で、bytesからクラスまたはインタフェースを作成してリンクします。このルックアップの「ルックアップ・モード」には、
PACKAGEアクセスが含まれている必要があります。これは、デフォルトの(package)メンバーがクラスからアクセス可能になるためです。PACKAGEルックアップ・モードは、ルックアップ・オブジェクトがランタイム・パッケージ(または適切に特権コードによって作成されたルックアップから、ランタイム・パッケージ内のターゲット・クラスに派生)の呼び出し側によって作成されたことを認証する役割を果たします。bytesパラメータは、ルックアップ・クラスと同じパッケージ内のクラス名を持つ、有効なクラス・ファイル(「Java Virtual Machine仕様」で定義されているとおり)のクラス・バイトです。このメソッドはクラス・イニシャライザを実行しません。 クラス・イニシャライザは、「Java言語仕様」の12.4セクションで説明されているように、後で実行できます。
- パラメータ:
bytes- クラス・バイト- 戻り値:
- クラスの
Classオブジェクト - スロー:
IllegalAccessException- このルックアップにPACKAGEアクセスがない場合ClassFormatError-bytesがClassFile構造でない場合IllegalArgumentException-bytesがルックアップ・クラスとは異なるパッケージ内のクラスを示している場合、またはbytesがクラスまたはインタフェース(ACC_MODULEフラグがaccess_flagsアイテムの値に設定されています)でない場合VerifyError- 新しく作成したクラスを検証できない場合LinkageError- 新しく作成されたクラスを他の理由でリンクできない場合NullPointerException-bytesがnullの場合- 導入されたバージョン:
- 9
- 関連項目:
-
defineHiddenClass
public MethodHandles.Lookup defineHiddenClass(byte[] bytes, boolean initialize, MethodHandles.Lookup.ClassOption... options) throws IllegalAccessException bytesからhiddenクラスまたはインタフェースを作成し、新しく作成されたクラスまたはインタフェースにLookupを返します。通常、クラスまたはインタフェース
Cは、Cを直接定義するか、別のクラス・ローダーに委譲するクラス・ローダーによって作成されます。 クラス・ローダーは、ClassLoader::defineClassを起動してCを直接定義します。これにより、Java Virtual Machineはclassファイル形式のパージされた表現からCを導出します。 クラス・ローダーの使用が望ましくない場合は、かわりにこのメソッドでクラスまたはインタフェースCを作成できます。 このメソッドは、ClassLoader::defineClassを起動せずに、Cを定義して作成できます。 かわりに、このメソッドは、次のルールを使用して、Java Virtual Machineがclassファイル形式でパージされた表現から非配列クラスまたはインタフェースCを導出するように配置することによって、Cを定義します:- この
Lookupの「ルックアップ・モード」には、「完全な権限」アクセスが含まれている必要があります。 このアクセス・レベルは、このLookupのルックアップ・クラスのモジュールにCを作成するために必要です。 -
bytesの紫色の表現は、サポートされているメジャーおよびマイナー・バージョンのClassFile構造(JVMS 4.1)である必要があります。 メジャー・バージョンおよびマイナー・バージョンは、このLookupのルックアップ・クラスのclassファイル・バージョンとは異なる場合があります。 -
this_classの値はconstant_pool表の有効な索引である必要があり、その索引のエントリは有効なCONSTANT_Class_info構造である必要があります。Nを、この構造体で指定された内部形式でエンコードされたバイナリ名にします。Nは、ルックアップ・クラスと同じパッケージ内のクラスまたはインタフェースを示す必要があります。 -
CNを文字列N + "." + <suffix>にします。ここで、<suffix>は非修飾名です。newBytesを、constant_pool表の追加エントリでbytesによって指定されるClassFile構造にし、CNのCONSTANT_Utf8_info構造体を示し、CONSTANT_Class_info構造体がthis_classによって示される新しいCONSTANT_Utf8_info構造体を参照するようにします。LをこのLookupのルックアップ・クラスの定義クラス・ローダーにします。Cは、JVMS 5.3.5のルールと同様に、名前CN、クラス・ローダーL、およびパージされた表現newBytesで導出されますが、次の調整があります:-
this_classによって示される定数では、単一の"."文字を含む名前を指定できます。ただし、これは内部形式の有効なバイナリ・クラスまたはインタフェース名ではありません。 - Java Virtual Machineは、
LをCの定義クラス・ローダーとしてマークしますが、Cの開始クラス・ローダーとして記録されるクラス・ローダーはありません。 -
Cは、このLookupのルックアップ・クラスと同じランタイムpackage、moduleおよび「保護ドメイン」を持つとみなされます。 -
N(内部形式でエンコードされたバイナリ名)を取得し、ASCIIフォワード・スラッシュをASCIIピリオドに置き換えることで、GNを取得したバイナリ名にします。Cを表すClassのインスタンスの場合:- これは有効なバイナリ・クラスまたはインタフェース名ではありませんが、
Class.getName()は文字列GN + "/" + <suffix>を返します。 - これは有効な型記述子名ではありませんが、
Class.descriptorString()は文字列"L" + N + "." + <suffix> + ";"を返します。 -
Cは「名目書式」で記述できないため、Class.describeConstable()は空のオプションを返します。
- これは有効なバイナリ・クラスまたはインタフェース名ではありませんが、
-
Cは導出された後、Java Virtual Machineによってリンクされます。 JVMS 5.4.3で指定されているようにリンクが発生しますが、次の調整が行われます:- 検証中に、
CNという名前のクラスをロードする必要がある場合は常に、試行が成功し、クラスCが生成されます。 クラス・ローダーからのリクエストは行われません。 -
this_classで示されたランタイム定数プールのエントリを解決しようとすると、シンボリック参照はCに解決されたとみなされ、解決は常にすぐに成功します。
initializeパラメータがtrueの場合、CはJava Virtual Machineによって初期化されます。新しく作成されたクラスまたはインタフェース
Cは、このメソッドによって返されるLookupオブジェクトの「ルックアップ・クラス」として機能します。Cは、定数プール・エントリを介して他のクラスまたはインタフェースがCを参照できないという意味でhiddenです。 つまり、非表示のクラスまたはインタフェースには、スーパータイプ、フィールド・タイプ、メソッド・パラメータ・タイプまたはメソッド戻り型として他のクラスで名前を付けることはできません。 これは、非表示のクラスまたはインタフェースにバイナリ名がないためであり、どのクラス定数プールにも記録できる内部形式がないためです。 非表示のクラスまたはインタフェースは、Class.forName(String, boolean, ClassLoader)、ClassLoader.loadClass(String, boolean)またはfindClass(String)では検出できず、JavaエージェントまたはJVM Tool Interfaceを使用するツール・エージェントでは「変更可能」ではありません。「クラス・ローダー」によって作成されたクラスまたはインタフェースは、そのクラス・ローダーと強力な関係を持ちます。 つまり、すべての
Classオブジェクトには、「定義済」が参照するClassLoaderへの参照が含まれます。 つまり、クラス・ローダーによって作成されたクラスは、その定義ローダーにアクセスできず、ガベージ・コレクタ(JLS 12.7)によって再利用される場合のみ、アンロードできます。 ただし、定義ローダーとしてマークされているクラス・ローダーが「到達可能」の場合でも、デフォルトで非表示クラスまたはインタフェースがアンロードされることがあります。 この動作は、非表示のクラスまたはインタフェースが、任意のクラス・ローダーによって定義された複数のクラスにサービスを提供する場合に便利です。 それ以外の場合、非表示のクラスまたはインタフェースは、非表示のクラスまたはインタフェースと同じ定義ローダーを持つ単一のクラス(または少数のクラス)にリンクできます。 このような場合、非表示クラスまたはインタフェースは通常のクラスまたはインタフェースと同時に使用する必要があり、STRONGオプションはoptionsで渡すことができます。 通常のクラスまたはインタフェースには独自の定義ローダーがあるため、非表示のクラスは、その定義ローダーとしてマークされたクラス・ローダーと同じ強力な関係を持つように配置されます。STRONGが使用されていない場合でも、defineHiddenClassの起動者は、Classオブジェクトが到達可能であることを確認することで、非表示のクラスまたはインタフェースをアンロードできない場合があります。アンロード特性は、定義時に非表示クラスごとに設定され、後で変更することはできません。 定義ローダーとしてマークされたクラス・ローダーから独立して非表示クラスをアンロードできるという利点は、アプリケーションで非常に多くの非表示クラスを作成できることです。 対照的に、
STRONGを使用すると、通常のクラスがクラス・ローダーによって作成された場合と同様に、JVMのメモリーが不足する可能性があります。ネスト内のクラスおよびインタフェースは、プライベート・メンバーへの相互アクセスを許可されます。 ネスト関係は、
classファイルのNestHost属性(JVMS 4.7.28)およびNestMembers属性(JVMS 4.7.29)によって決定されます。 非表示クラスにはバイナリ名がないため、デフォルトでは、非表示クラスはそれ自体のみで構成されるネストに属します。NESTMATEオプションをoptionsに渡して、非表示のクラスまたはインタフェースCをネストのメンバーとして作成できます。Cが属するネストは、Cが導出されたClassFile構造のNestHost属性に基づいていません。 かわりに、次のルールによってCのネスト・ホストが決定されます:- この
Lookupのルックアップ・クラスのネスト・ホストが以前に決定されている場合は、Hをルックアップ・クラスのネスト・ホストにします。 それ以外の場合は、JVMS 5.4.4のアルゴリズムを使用してルックアップ・クラスのネスト・ホストが決定され、Hが生成されます。 Cのネストされたホストは、ルックアップ・クラスのネストされたホストであるHと判断されます。
非表示のクラスまたはインタフェースは直列化可能でもかまいませんが、インスタンスが適切にシリアライズおよび直列化復元されるようにするには、カスタム・シリアライズ・メカニズムが必要です。 デフォルトの直列化メカニズムでは、クラス名で検出可能なクラスおよびインタフェースのみがサポートされます。
- パラメータ:
bytes- 「Java Virtual Machine仕様」で定義された有効なclassファイルの形式でクラス・データを構成するバイト。initialize-trueの場合、そのクラスが初期化される。options- 「クラス・オプション」- 戻り値:
- originalおよび「完全な権限」アクセス権を持つ非表示クラスの
Lookupオブジェクト - スロー:
IllegalAccessException- このLookupに「完全な権限」アクセス権がない場合ClassFormatError-bytesがClassFile構造でない場合UnsupportedClassVersionError-bytesがサポートされているメジャー・バージョンまたはマイナー・バージョンでない場合IllegalArgumentException-bytesがルックアップ・クラスとは異なるパッケージ内のクラスを示している場合、またはbytesがクラスまたはインタフェース(ACC_MODULEフラグがaccess_flagsアイテムの値に設定されています)でない場合IncompatibleClassChangeError-Cの直接のスーパークラスとして指定されたクラスまたはインタフェースが実際にインタフェースである場合、またはCの直接のスーパー・インタフェースとして指定されたクラスまたはインタフェースのいずれかが実際のインタフェースにない場合ClassCircularityError-Cのスーパークラスまたはスーパー・インタフェースのいずれかがC自体の場合VerifyError- 新しく作成したクラスを検証できない場合LinkageError- 新しく作成されたクラスを他の理由でリンクできない場合NullPointerException- パラメータがnullの場合- Java言語仕様を参照してください:
-
12.7 クラスおよびインタフェースのアンロード
- Java Virtual Machine仕様を参照してください:
-
4.2.1 バイナリ・クラス名およびインタフェース名
4.2.2 未修飾名
4.7.28NestHost属性
4.7.29NestMembers属性
5.4 .3.1 クラスおよびインタフェースの解決
5.4.4 アクセス制御
5.3.5classファイル表現からのClassの導出
5.4 リンク
5.5 初期化 - 導入されたバージョン:
- 15
- 関連項目:
- この
-
defineHiddenClassWithClassData
public MethodHandles.Lookup defineHiddenClassWithClassData(byte[] bytes, Object classData, boolean initialize, MethodHandles.Lookup.ClassOption... options) throws IllegalAccessException 関連付けられた「クラス・データ」を使用してbytesからhiddenクラスまたはインタフェースを作成し、新しく作成されたクラスまたはインタフェースでLookupを返します。このメソッドは、クラス初期化子の最初の命令で指定された
classDataで初期化されたprivate static final 「名前なし」フィールドを非表示クラスに注入する場合と同様に、defineHiddenClass(bytes, initialize, options)を呼び出すのと同じです。 新しく作成されたクラスは、Java Virtual Machineによってリンクされます。MethodHandles::classDataおよびMethodHandles::classDataAtメソッドを使用して、classDataを取得できます。- APIのノート:
- フレームワークでは、1つ以上のオブジェクトを含むクラス・データを持つ非表示クラスを作成し、ブートストラップ・メソッドを介して動的に計算された定数としてクラス・データをロードできます。
Class dataには、新しく定義された非表示クラスによって作成されたルックアップ・オブジェクトからのみアクセスできますが、同じネストされた(ネストしたユーザーがアクセスできるprivate staticフィールドとは異なります)内の他のメンバーからはアクセスできません。 クラス・データを介して配列やその他の可変構造体を渡す場合などは、可変性に注意してください。 クラス・データに格納されている値を実行時に変更すると、予期しない動作が発生する可能性があります。 クラス・データがListの場合、たとえばList::ofを介して変更できないようにすることをお薦めします。 - パラメータ:
bytes- クラス・バイトclassData- 事前初期化されたクラス・データinitialize-trueの場合、そのクラスが初期化される。options- 「クラス・オプション」- 戻り値:
- originalおよび「完全な権限」アクセス権を持つ非表示クラスの
Lookupオブジェクト - スロー:
IllegalAccessException- このLookupに「完全な権限」アクセス権がない場合ClassFormatError-bytesがClassFile構造でない場合UnsupportedClassVersionError-bytesがサポートされているメジャー・バージョンまたはマイナー・バージョンでない場合IllegalArgumentException-bytesがルックアップ・クラスとは異なるパッケージ内のクラスを示している場合、またはbytesがクラスまたはインタフェース(ACC_MODULEフラグがaccess_flagsアイテムの値に設定されています)でない場合IncompatibleClassChangeError-Cの直接のスーパークラスとして指定されたクラスまたはインタフェースが実際にインタフェースである場合、またはCの直接のスーパー・インタフェースとして指定されたクラスまたはインタフェースのいずれかが実際のインタフェースにない場合ClassCircularityError-Cのスーパークラスまたはスーパー・インタフェースのいずれかがC自体の場合VerifyError- 新しく作成したクラスを検証できない場合LinkageError- 新しく作成されたクラスを他の理由でリンクできない場合NullPointerException- パラメータがnullの場合- Java言語仕様を参照してください:
-
12.7 クラスおよびインタフェースのアンロード
- Java Virtual Machine仕様を参照してください:
-
4.2.1 バイナリ・クラス名およびインタフェース名
4.2.2 未修飾名
4.7.28NestHost属性
4.7.29NestMembers属性
5.4 .3.1 クラスおよびインタフェースの解決
5.4.4 アクセス制御
5.3.5classファイル表現からのClassの導出
5.4 リンク
5.5 初期化 - 導入されたバージョン:
- 16
- 関連項目:
-
toString
public String toString()ルックアップを行うクラスの名前、"/"および「前のルックアップ・クラス」の名前(存在する場合)が表示されます。 (名前は、Class.getNameによって報告される名前です。) このルックアップに許可されるアクセスに制限がある場合、そのことを示すために、スラッシュとキーワードで構成される接尾辞がクラス名に追加されます。 キーワードは許可される最強のアクセスを表しており、次のように選択されます。- アクセスが一切許可されない場合、接尾辞は「/noaccess」になります。
- 無条件アクセスのみが許可される場合、サフィクスは"/publicLookup"です。
- エクスポートされたパッケージ内の型へのパブリック・アクセスのみが許可されている場合、サフィクスは"/public"です。
- パブリック・アクセスとモジュール・アクセスのみが許可されている場合、サフィクスは"/module"です。
- パブリック・アクセスおよびパッケージ・アクセスが許可される場合、サフィクスは"/package"です。
- パブリック、パッケージおよびプライベート・アクセスが許可される場合、サフィクスは"/private"です。
MethodHandles.lookupから取得されたオブジェクトにのみ当てはまります。Lookup.inによって作成されたオブジェクトには、常にアクセスが制限され、サフィクスが表示されます。(protectedアクセスがprivateアクセスより強いというのは、奇妙に感じるかもしれません。 packageアクセスから独立して見た場合、protectedアクセスが最初に失われるものになりますが、それは、呼出し元と呼出し先の間に直接的なサブクラス関係が必要になるからです。)
-
findStatic
public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException staticメソッドのメソッド・ハンドルを生成します。 メソッド・ハンドルの型は、メソッドの型になります。 (staticメソッドはレシーバを取らないため、findVirtualやfindSpecialのように、メソッド・ハンドルの型に追加のレシーバ引数が挿入されることはありません。) このメソッドとそのすべての引数型にルックアップ・オブジェクトからアクセスできる必要があります。返されるメソッド・ハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。返されるメソッド・ハンドルが呼び出された場合、そのメソッドのクラスは初期化されます(まだ初期化されていない場合)。
例:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, "asList", methodType(List.class, Object[].class)); assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());- パラメータ:
refc- メソッドのアクセス元となるクラスname- メソッドの名前type- メソッドの型- 戻り値:
- 目的のメソッド・ハンドル
- スロー:
NoSuchMethodException- メソッドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドがstaticでない場合、あるいはメソッドの可変引数修飾子ビットが設定されてasVarargsCollectorが失敗した場合NullPointerException- いずれかの引数がnullの場合
-
findVirtual
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException 仮想メソッドのメソッド・ハンドルを生成します。 メソッド・ハンドルの型は、メソッドの型の先頭にレシーバの型(通常はrefc)を追加したものになります。 このメソッドとそのすべての引数型にルックアップ・オブジェクトからアクセスできる必要があります。ハンドルが呼び出されると、最初の引数がレシーバとして扱われ、非駆動型のメソッドがディスパッチされ、どのメソッド実装を入力するかが決定されます。 プライベート・メソッドの場合、
refc内の名前付きメソッドが受信側で呼び出されます。 (このディスパッチ・アクションは、invokevirtualまたはinvokeinterface命令によって実行されるアクションと同一です。)ルックアップ・クラスがメンバーにアクセスする完全な権限を持っている場合、最初の引数の型は
refcになります。 それ以外の場合、メンバーはprotectedである必要があり、最初の引数の型はルックアップ・クラスに制限されます。返されるメソッド・ハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。invokevirtual命令とfindVirtualによって生成されるメソッド・ハンドルとの間の一般的な等価性のために、クラスがMethodHandleで名前文字列がinvokeExactまたはinvokeの場合は、結果のメソッド・ハンドルは同じtype引数のMethodHandles.exactInvokerまたはMethodHandles.invokerで生成されたものと同等です。クラスが
VarHandleで、名前文字列がsignature-polymorphicアクセス・モード・メソッドの名前に対応する場合、生成されるメソッド・ハンドルは、名前文字列に対応するアクセス・モードと、同じtype引数を持つMethodHandles.varHandleInvoker(java.lang.invoke.VarHandle.AccessMode, java.lang.invoke.MethodType)によって生成されるものと同等です。例:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle MH_concat = publicLookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, "hashCode", methodType(int.class)); MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, "hashCode", methodType(int.class)); assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); // interface method: MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, "subSequence", methodType(CharSequence.class, int.class, int.class)); assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); // constructor "internal method" must be accessed differently: MethodType MT_newString = methodType(void.class); //()V for new String() try { assertEquals("impossible", lookup() .findVirtual(String.class, "<init>", MT_newString)); } catch (NoSuchMethodException ex) { } // OK MethodHandle MH_newString = publicLookup() .findConstructor(String.class, MT_newString); assertEquals("", (String) MH_newString.invokeExact());- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースname- メソッドの名前type- メソッドの型(レシーバ引数は含まない)- 戻り値:
- 目的のメソッド・ハンドル
- スロー:
NoSuchMethodException- メソッドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドがstatic,の場合、あるいはメソッドの可変引数修飾子ビットが設定されてasVarargsCollectorが失敗した場合NullPointerException- いずれかの引数がnullの場合
-
findConstructor
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException 指定された型のコンストラクタを使ってオブジェクトの作成と初期化を行うメソッド・ハンドルを生成します。 メソッド・ハンドルのパラメータの型はコンストラクタのパラメータの型になり、戻り値の型はコンストラクタのクラスへの参照になります。 コンストラクタとそのすべての引数型にルックアップ・オブジェクトからアクセスできる必要があります。要求する型の戻り値の型は
voidでなければいけません。 (これは、JVMのコンストラクタ型記述子の扱いに準拠しています。)返されるメソッド・ハンドルの引数が可変引数になるのは、コンストラクタの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。返されるメソッド・ハンドルが呼び出された場合、そのコンストラクタのクラスは初期化されます(まだ初期化されていない場合)。
例:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle MH_newArrayList = publicLookup().findConstructor( ArrayList.class, methodType(void.class, Collection.class)); Collection orig = Arrays.asList("x", "y"); Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); assert(orig != copy); assertEquals(orig, copy); // a variable-arity constructor: MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( ProcessBuilder.class, methodType(void.class, String[].class)); ProcessBuilder pb = (ProcessBuilder) MH_newProcessBuilder.invoke("x", "y", "z"); assertEquals("[x, y, z]", pb.command().toString());- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースtype- メソッドの型(レシーバ引数は含めず、戻り値の型はvoidにする)- 戻り値:
- 目的のメソッド・ハンドル
- スロー:
NoSuchMethodException- コンストラクタが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていてasVarargsCollectorが失敗した場合NullPointerException- いずれかの引数がnullの場合
-
findClass
public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException このLookupオブジェクト「解決された場合」によってldcの命令で定義された参照コンテキストから名前でクラスを検索します。 このような解像度(JVMS 5.4.3.1で指定)では、クラスを検索してロードし、クラスがこのルックアップ・オブジェクトにアクセス可能かどうかを判断します。クラスまたはインタフェースの場合、名前は「バイナリ名」です。
nディメンションの配列クラスの場合、名前は'['のnオカレンスで始まり、その後にClass.getName()で指定された「表」でエンコードされた要素タイプが続きます。ここでのルックアップ・コンテキストは、「ルックアップ・クラス」、そのクラス・ローダーおよび「ルックアップ・モード」によって決定されます。
- パラメータ:
targetName- クラスの「バイナリ名」または配列クラスを表す文字列- 戻り値:
- リクエストされたクラス。
- スロー:
LinkageError- リンケージに失敗した場合ClassNotFoundException- ルックアップ・クラスのローダーによってクラスをロードできない場合。IllegalAccessException- クラスにアクセスできない場合は、許可されたアクセス・モードを使用します。NullPointerException-targetNameがnullの場合- Java Virtual Machine仕様を参照してください:
-
5.4.3.1 クラスおよびインタフェースの解決
- 導入されたバージョン:
- 9
-
ensureInitialized
public <T> Class<T> ensureInitialized(Class<T> targetClass) throws IllegalAccessException targetClassが初期化されていることを確認します。 初期化するクラスは、このLookupオブジェクトへの「アクセシビリティ」である必要があります。 JVMS 5.5で指定されているように、targetClassが初期化されていない場合は、このメソッドによって初期化されます。このメソッドは、
targetClassが完全に初期化されたとき、またはtargetClassが現在のスレッドによって初期化されているときに返します。- 型パラメータ:
T- 初期化するクラスのタイプ- パラメータ:
targetClass- 初期化されるクラス- 戻り値:
- 初期化されているか、現在のスレッドによって初期化されている
targetClass。 - スロー:
IllegalArgumentException-targetClassがプリミティブ型、voidまたは配列クラスの場合IllegalAccessException-targetClassがこのルックアップに対する「アクセシビリティ」でない場合ExceptionInInitializerError- このメソッドによって起動されたクラスの初期化が失敗した場合- Java Virtual Machine仕様を参照してください:
-
「5.5 初期化」
- 導入されたバージョン:
- 15
-
accessClass
public <T> Class<T> accessClass(Class<T> targetClass) throws IllegalAccessException このLookupオブジェクトで定義されたルックアップ・コンテキストからクラスにアクセスできるかどうかを決定します。 クラスの静的イニシャライザが実行されていません。targetClassが配列クラスの場合、配列クラスの要素タイプにアクセスできると、targetClassにアクセスできます。 それ以外の場合、targetClassは、次のようにアクセス可能であると判断されます。targetClassがルックアップ・クラスと同じモジュール内にある場合、ルックアップ・クラスはモジュールM1のLCで、前のルックアップ・クラスはモジュールM0またはnullに存在しない場合、targetClassは、次のいずれかがtrueの場合にのみアクセスできます:- この参照に
PRIVATEアクセス権がある場合、targetClassはLCの同じネストに含まれているLCまたは他のクラスです。 - この参照に
PACKAGEアクセス権がある場合、targetClassはLCの同じランタイム・パッケージに含まれます。 - この参照に
MODULEアクセス権がある場合、targetClassはM1の公開タイプです。 - この参照に
PUBLICアクセス権がある場合、targetClassは、以前の参照クラスが存在する場合に少なくともM0にエクスポートされるパッケージのパブリック・タイプです。それ以外の場合、targetClassはM1で無条件にエクスポートされたパッケージ内のパブリック・タイプです。
そうでない場合、この参照に
UNCONDITIONALアクセス権が含まれていると、タイプが無条件でエクスポートされたパッケージの場合、この参照ではすべてのモジュールの公開タイプにアクセスできます。それ以外の場合、
targetClassはlookupClassとは異なるモジュールに存在し、この参照にPUBLICアクセス権がない場合、lookupClassにアクセスできません。それ以外の場合でこの参照に「前のルックアップ・クラス」が含まれない場合、
M1はlookupClassを含むモジュール、M2はtargetClassを含むモジュールであり、次の場合にのみtargetClassにアクセスできますM1はM2を読み取り、targetClassはパブリックで、M2によって少なくともM1にエクスポートされたパッケージ内にあります。
それ以外の場合で、この参照に「前のルックアップ・クラス」、
M1およびM2が以前と同様であり、M0が以前の参照クラスを含むモジュールである場合、targetClassは次のいずれかがtrueである場合にのみアクセス可能です:targetClassはM0にあり、M1はM0を読み取り、タイプは少なくともM1にエクスポートされるパッケージ内にあります。targetClassはM1にあり、M0はM1を読み取り、タイプは少なくともM0にエクスポートされるパッケージ内にあります。targetClassは3つ目のモジュールM2に含まれ、M0とM1は両方ともM2を読み取り、タイプは少なくともM0とM2の両方にエクスポートされるパッケージに含まれます。
それ以外の場合、
targetClassにはアクセスできません。- 型パラメータ:
T- アクセス・チェックされるクラスのタイプ- パラメータ:
targetClass- アクセス・チェックされるクラス- 戻り値:
- アクセス・チェックが行われた
targetClass - スロー:
IllegalAccessException- ルックアップ・クラスおよび前のルックアップ・クラスが存在する場合、許可されたアクセス・モードを使用してこのクラスにアクセスできない場合。NullPointerException-targetClassがnullの場合- 導入されたバージョン:
- 9
- 関連項目:
- この参照に
-
findSpecial
public MethodHandle findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException 仮想メソッドの早期にバインドされるメソッド・ハンドルを生成します。 明示的に指定されたspecialCaller内のinvokespecial命令から呼び出されたかのように、レシーバでのメソッドのオーバーライド・チェックをバイパスします。 メソッド・ハンドルの型はメソッドのもので、適切に制限されたレシーバ型が追加されます。 (レシーバ型はspecialCallerまたはサブタイプです。) このメソッドとそのすべての引数型にルックアップ・オブジェクトからアクセスできる必要があります。メソッド解決の前に、明示的に指定された呼出し元クラスがルックアップ・クラスと同一でない場合、またはこのルックアップ・オブジェクトがprivateアクセス特権を持たない場合は、アクセスが失敗します。
返されるメソッド・ハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。(Note: "<init>"という名前のJVM内部メソッドは、
invokespecial命令が特別な状況でそれらを参照できる場合でも、このAPIには表示されません。findConstructorを使用して、安全な方法でインスタンス初期化メソッドにアクセスします。)例:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... static class Listie extends ArrayList { public String toString() { return "[wee Listie]"; } static Lookup lookup() { return MethodHandles.lookup(); } } ... // no access to constructor via invokeSpecial: MethodHandle MH_newListie = Listie.lookup() .findConstructor(Listie.class, methodType(void.class)); Listie l = (Listie) MH_newListie.invokeExact(); try { assertEquals("impossible", Listie.lookup().findSpecial( Listie.class, "<init>", methodType(void.class), Listie.class)); } catch (NoSuchMethodException ex) { } // OK // access to super and self methods via invokeSpecial: MethodHandle MH_super = Listie.lookup().findSpecial( ArrayList.class, "toString" , methodType(String.class), Listie.class); MethodHandle MH_this = Listie.lookup().findSpecial( Listie.class, "toString" , methodType(String.class), Listie.class); MethodHandle MH_duper = Listie.lookup().findSpecial( Object.class, "toString" , methodType(String.class), Listie.class); assertEquals("[]", (String) MH_super.invokeExact(l)); assertEquals(""+l, (String) MH_this.invokeExact(l)); assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method try { assertEquals("inaccessible", Listie.lookup().findSpecial( String.class, "toString", methodType(String.class), Listie.class)); } catch (IllegalAccessException ex) { } // OK Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースname- メソッドの名前(「<init>」であってはいけない)type- メソッドの型(レシーバ引数は含まない)specialCaller-invokespecialを実行する、提案された呼出し元クラス- 戻り値:
- 目的のメソッド・ハンドル
- スロー:
NoSuchMethodException- メソッドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドがstatic,の場合、あるいはメソッドの可変引数修飾子ビットが設定されてasVarargsCollectorが失敗した場合NullPointerException- いずれかの引数がnullの場合
-
findGetter
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException 非staticフィールドに対する読取りアクセスを提供するメソッド・ハンドルを生成します。 メソッド・ハンドルの型に含まれる戻り値の型は、フィールドの値の型になります。 メソッド・ハンドルの単一の引数は、フィールドを含むインスタンスです。 ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースname- フィールドの名前type- フィールドの型- 戻り値:
- フィールドから値をロードできるメソッド・ハンドル
- スロー:
NoSuchFieldException- フィールドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはフィールドがstaticの場合NullPointerException- いずれかの引数がnullの場合- 関連項目:
-
findSetter
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException 非staticフィールドに対する書込みアクセスを提供するメソッド・ハンドルを生成します。 このメソッド・ハンドルの型に含まれる戻り値の型は、voidになります。 メソッド・ハンドルが取る2つの引数は、フィールドを含むインスタンスと、格納する値です。 2番目の引数の型は、フィールドの値の型になります。 ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースname- フィールドの名前type- フィールドの型- 戻り値:
- フィールドに値を格納できるメソッド・ハンドル
- スロー:
NoSuchFieldException- フィールドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはフィールドがstaticまたはfinalである場合NullPointerException- いずれかの引数がnullの場合- 関連項目:
-
findVarHandle
public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException 型recvのクラスで宣言された型typeの非静的フィールドnameへのアクセスを提供するVarHandleを生成します。 VarHandleの変数型はtypeで、1つの座標型recvがあります。ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。
返されたVarHandleの特定のアクセス・モードは、次の条件ではサポートされません:
- フィールドが
finalと宣言されている場合、書込み、アトミック・アップデート、数値アトミック・アップデートおよびビット単位アトミック・アップデート・アクセス・モードはサポートされていません。 - フィールド・タイプが
byte,short,char,int,long,floatまたはdouble以外の場合、数値アトミック更新アクセス・モードはサポートされていません。 - フィールド・タイプが
boolean,byte,short,char,intまたはlong以外の場合、ビット単位のアトミック更新アクセス・モードはサポートされていません。
フィールドが
volatileと宣言されている場合、返されたVarHandleは、指定されたアクセス・モードに従って、フィールド(volatile宣言を効果的に無視)へのアクセスをオーバーライドします。フィールド型が
floatまたはdoubleの場合、数値およびアトミック更新アクセス・モードはビット単位の表現(それぞれFloat.floatToRawIntBits(float)とDouble.doubleToRawLongBits(double)を参照してください)を使用して値を比較します。- APIのノート:
- 数値およびアトミック更新アクセス・モードで実行される
float値またはdouble値のビット単位比較は、プリミティブ==演算子およびFloat.equals(java.lang.Object)およびDouble.equals(java.lang.Object)メソッドとは異なります。特に、NaN値の比較または-0.0と+0.0の比較については異なります。 この操作が予期せず失敗する可能性があるため、これらの値との比較および設定または比較および交換操作の実行時には注意が必要です。 JavaではNaNとみなされるNaN値は多数ありますが、Javaで提供されるIEEE 754浮動小数点演算では区別できません。 予期される値または証人値がNaN値で、(おそらくプラットフォーム固有の方法で)を別のNaN値に変換し、異なるビット単位の表現(詳細はFloat.intBitsToFloat(int)またはDouble.longBitsToDouble(long)を参照してください)を持つ場合、操作の失敗が発生する可能性があります。 値-0.0および+0.0は、ビット単位の表現は異なりますが、プリミティブ==演算子を使用するときは等しいとみなされます。 たとえば、数値アルゴリズムが予期される値を-0.0と計算し、以前に証人値を+0.0と計算した場合、操作の失敗が発生する可能性があります。 - パラメータ:
recv- 非静的フィールドを宣言する受信側クラス(R型)name- フィールドの名前type-T型のフィールドの型- 戻り値:
- 非静的フィールドへのアクセスを提供するVarHandle。
- スロー:
NoSuchFieldException- フィールドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはフィールドがstaticの場合NullPointerException- いずれかの引数がnullの場合- 導入されたバージョン:
- 9
- フィールドが
-
findStaticGetter
public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException staticフィールドに対する読取りアクセスを提供するメソッド・ハンドルを生成します。 メソッド・ハンドルの型に含まれる戻り値の型は、フィールドの値の型になります。 メソッド・ハンドルは引数を一切取りません。 ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。返されるメソッド・ハンドルが呼び出された場合、そのフィールドのクラスは初期化されます(まだ初期化されていない場合)。
- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースname- フィールドの名前type- フィールドの型- 戻り値:
- フィールドから値をロードできるメソッド・ハンドル
- スロー:
NoSuchFieldException- フィールドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはフィールドがstaticでない場合NullPointerException- いずれかの引数がnullの場合
-
findStaticSetter
public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException staticフィールドに対する書込みアクセスを提供するメソッド・ハンドルを生成します。 このメソッド・ハンドルの型に含まれる戻り値の型は、voidになります。 メソッド・ハンドルは、フィールドの値の型を持つ単一の引数(格納する値)を取ります。 ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。返されるメソッド・ハンドルが呼び出された場合、そのフィールドのクラスは初期化されます(まだ初期化されていない場合)。
- パラメータ:
refc- メソッドのアクセス元となるクラスまたはインタフェースname- フィールドの名前type- フィールドの型- 戻り値:
- フィールドに値を格納できるメソッド・ハンドル
- スロー:
NoSuchFieldException- フィールドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはフィールドがstaticでないかfinalである場合NullPointerException- いずれかの引数がnullの場合
-
findStaticVarHandle
public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException 型declのクラスで宣言された型typeの静的フィールドnameへのアクセスを提供するVarHandleを生成します。 VarHandleの変数型はtypeで、座標型はありません。ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。
戻されたVarHandleが操作されている場合は、宣言クラスがまだ初期化されていない場合は初期化されます。
返されたVarHandleの特定のアクセス・モードは、次の条件ではサポートされません:
- フィールドが
finalと宣言されている場合、書込み、アトミック・アップデート、数値アトミック・アップデートおよびビット単位アトミック・アップデート・アクセス・モードはサポートされていません。 - フィールド・タイプが
byte,short,char,int,long,floatまたはdouble以外の場合、数値アトミック更新アクセス・モードはサポートされていません。 - フィールド・タイプが
boolean,byte,short,char,intまたはlong以外の場合、ビット単位のアトミック更新アクセス・モードはサポートされていません。
フィールドが
volatileと宣言されている場合、返されたVarHandleは、指定されたアクセス・モードに従って、フィールド(volatile宣言を効果的に無視)へのアクセスをオーバーライドします。フィールド型が
floatまたはdoubleの場合、数値およびアトミック更新アクセス・モードはビット単位の表現(それぞれFloat.floatToRawIntBits(float)とDouble.doubleToRawLongBits(double)を参照してください)を使用して値を比較します。- APIのノート:
- 数値およびアトミック更新アクセス・モードで実行される
float値またはdouble値のビット単位比較は、プリミティブ==演算子およびFloat.equals(java.lang.Object)およびDouble.equals(java.lang.Object)メソッドとは異なります。特に、NaN値の比較または-0.0と+0.0の比較については異なります。 この操作が予期せず失敗する可能性があるため、これらの値との比較および設定または比較および交換操作の実行時には注意が必要です。 JavaではNaNとみなされるNaN値は多数ありますが、Javaで提供されるIEEE 754浮動小数点演算では区別できません。 予期される値または証人値がNaN値で、(おそらくプラットフォーム固有の方法で)を別のNaN値に変換し、異なるビット単位の表現(詳細はFloat.intBitsToFloat(int)またはDouble.longBitsToDouble(long)を参照してください)を持つ場合、操作の失敗が発生する可能性があります。 値-0.0および+0.0は、ビット単位の表現は異なりますが、プリミティブ==演算子を使用するときは等しいとみなされます。 たとえば、数値アルゴリズムが予期される値を-0.0と計算し、以前に証人値を+0.0と計算した場合、操作の失敗が発生する可能性があります。 - パラメータ:
decl- 静的フィールドを宣言するクラスname- フィールドの名前type-T型のフィールドの型- 戻り値:
- 静的フィールドにアクセスできるVarHandle
- スロー:
NoSuchFieldException- フィールドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはフィールドがstaticでない場合NullPointerException- いずれかの引数がnullの場合- 導入されたバージョン:
- 9
- フィールドが
-
bind
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException 非staticメソッドの早期バインド・メソッド・ハンドルを生成します。 レシーバのスーパー・タイプdefc内では、指定された名前と型を持つメソッドにルックアップ・クラスからアクセスできる必要があります。 このメソッドとそのすべての引数型にルックアップ・オブジェクトからアクセスできる必要があります。 メソッド・ハンドルの型はメソッドの型であり、追加のレシーバ・パラメータは一切挿入されません。 指定されたレシーバがメソッド・ハンドルにバインドされるため、メソッド・ハンドルが呼び出されるたびに要求されたメソッドが指定されたレシーバ上で呼び出されるようになります。返されるメソッド・ハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット(
0x0080)が設定されており、かつ、末尾の配列引数が唯一の引数でない場合だけです。 (末尾の配列引数が唯一の引数である場合、指定されたレシーバの値はその引数にバインドされます。)これは、次のコードとほぼ同等ですが、次のような違いがあります:
ここで、import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle mh0 = lookup().findVirtual(defc, name, type); MethodHandle mh1 = mh0.bindTo(receiver); mh1 = mh1.withVarargs(mh0.isVarargsCollector()); return mh1;defcはreceiver.getClass()またはそのクラスのスーパー・タイプのいずれかであり、その中では、要求されたメソッドにルックアップ・クラスからアクセスできます。 (bindとは異なり、bindToは可変の配列を保持しません。 また、bindToは、bindがIllegalAccessExceptionをスローするインスタンスでClassCastExceptionをスローできます(メンバーがprotectedで、レシーバがfindVirtualによってルックアップ・クラスに制限されている場合など)- パラメータ:
receiver- メソッドのアクセス元となるオブジェクトname- メソッドの名前type- メソッドの型(レシーバ引数は含まない)- 戻り値:
- 目的のメソッド・ハンドル
- スロー:
NoSuchMethodException- メソッドが存在しない場合IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていてasVarargsCollectorが失敗した場合NullPointerException- いずれかの引数がnullの場合- 関連項目:
-
unreflect
public MethodHandle unreflect(Method m) throws IllegalAccessException ルックアップ・クラスがアクセス権を持つ場合に、mへの直接メソッド・ハンドルを作成します。 mがstaticでない場合、レシーバ引数が最初の引数とみなされます。 mがvirtualの場合、すべての呼出しでオーバーライドが尊重されます。 Core Reflection APIと異なり、例外はラップされません。 メソッド・ハンドルの型は、メソッドの型の先頭にレシーバの型を追加したものになります(ただし、メソッドがstaticでない場合のみ)。 メソッドのaccessibleフラグが設定されていない場合、ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。 mがpublicでない場合、結果となるハンドルを信頼できない相手と共有しないでください。返されるメソッド・ハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。mがstaticで、返されるメソッド・ハンドルが呼び出された場合、そのメソッドのクラスは初期化されます(まだ初期化されていない場合)。
- パラメータ:
m- リフレクトされたメソッド- 戻り値:
- リフレクトされたメソッドを呼び出すことができるメソッド・ハンドル
- スロー:
IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていてasVarargsCollectorが失敗した場合NullPointerException- 引数がnullの場合
-
unreflectSpecial
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException リフレクトされたメソッドのメソッド・ハンドルを生成します。 明示的に指定されたspecialCaller内のinvokespecial命令から呼び出されたかのように、レシーバでのメソッドのオーバーライド・チェックをバイパスします。 メソッド・ハンドルの型はメソッドのもので、適切に制限されたレシーバ型が追加されます。 (レシーバ型はspecialCallerまたはサブタイプです。) メソッドのaccessibleフラグが設定されていない場合、invokespecial命令がリンクされていたかのように、ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。メソッド解決の前に、明示的に指定された呼出し元クラスがルックアップ・クラスと同一でない場合、またはこのルックアップ・オブジェクトがprivateアクセス特権を持たない場合は、アクセスが失敗します。
返されるメソッド・ハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。- パラメータ:
m- リフレクトされたメソッドspecialCaller- メソッドを形式上呼び出すクラス- 戻り値:
- リフレクトされたメソッドを呼び出すことができるメソッド・ハンドル
- スロー:
IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドがstatic,の場合、あるいはメソッドの可変引数修飾子ビットが設定されてasVarargsCollectorが失敗した場合NullPointerException- いずれかの引数がnullの場合
-
unreflectConstructor
public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException リフレクトされたコンストラクタのメソッド・ハンドルを生成します。 メソッド・ハンドルの型は、コンストラクタの型で、戻り値の型を宣言元クラスに変更したものになります。 メソッド・ハンドルはnewInstance操作を実行し、メソッド・ハンドルに渡された引数に基づいてコンストラクタのクラスの新しいインスタンスを作成します。コンストラクタの
accessibleフラグが設定されていない場合、ルックアップ・クラスに代わって即座にアクセス・チェックが実行されます。返されるメソッド・ハンドルの引数が可変引数になるのは、コンストラクタの可変引数修飾子ビット(
0x0080)が設定されている場合だけです。返されるメソッド・ハンドルが呼び出された場合、そのコンストラクタのクラスは初期化されます(まだ初期化されていない場合)。
- パラメータ:
c- リフレクトされたコンストラクタ- 戻り値:
- リフレクトされたコンストラクタを呼び出すことができるメソッド・ハンドル
- スロー:
IllegalAccessException- アクセス・チェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていてasVarargsCollectorが失敗した場合NullPointerException- 引数がnullの場合
-
unreflectGetter
public MethodHandle unreflectGetter(Field f) throws IllegalAccessException リフレクトされたフィールドに対する読取りアクセス権を提供するメソッド・ハンドルを生成します。 メソッド・ハンドルの型に含まれる戻り値の型は、フィールドの値の型になります。 フィールドがstaticの場合、メソッド・ハンドルには引数は必要ありません。 それ以外の場合、その単一の引数は、フィールドを含むインスタンスになります。Fieldオブジェクトのaccessibleフラグが設定されていない場合は、ルックアップ・クラスのかわりにアクセス・チェックが即時に実行されます。フィールドがstaticで、返されるメソッド・ハンドルが呼び出された場合、そのフィールドのクラスは初期化されます(まだ初期化されていない場合)。
- パラメータ:
f- リフレクトされたフィールド- 戻り値:
- リフレクトされたフィールドから値をロードできるメソッド・ハンドル
- スロー:
IllegalAccessException- アクセス・チェックが失敗した場合NullPointerException- 引数がnullの場合
-
unreflectSetter
public MethodHandle unreflectSetter(Field f) throws IllegalAccessException リフレクトされたフィールドに対する書込みアクセス権を提供するメソッド・ハンドルを生成します。 このメソッド・ハンドルの型に含まれる戻り値の型は、voidになります。 フィールドがstaticの場合、メソッド・ハンドルは、フィールド値の型の単一の引数(格納される値)を取ります。 それ以外の場合、2つの引数は、フィールドを含むインスタンスと格納する値になります。Fieldオブジェクトのaccessibleフラグが設定されていない場合は、ルックアップ・クラスのかわりにアクセス・チェックが即時に実行されます。フィールドが
finalの場合、Field.setについてドキュメント化されている特定の狭い状況を除き、書込みアクセスは許可されず、アクセス・チェックが失敗します。 メソッド・ハンドルが返されるのは、Fieldオブジェクトのsetメソッドへの対応するコールが正常に返された場合のみです。 具体的には、staticとfinalの両方であるフィールドを設定しない場合があります。フィールドが
staticで、返されたメソッド・ハンドルが呼び出された場合、フィールド・クラスは、初期化されていなければ初期化されます。- パラメータ:
f- リフレクトされたフィールド- 戻り値:
- リフレクトされたフィールドに値を格納できるメソッド・ハンドル
- スロー:
IllegalAccessException- アクセス・チェックに失敗した場合、またはフィールドがfinalであり、Fieldオブジェクトで書込みアクセスが有効になっていない場合NullPointerException- 引数がnullの場合
-
unreflectVarHandle
public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException クラスRで宣言されたT型の反映されたフィールドfへのアクセスを提供するVarHandleを生成します。 VarHandleの変数型はTです。 フィールドが非静的である場合、VarHandleには1つの座標型Rがあります。 それ以外の場合、フィールドは静的であり、VarHandleには座標型がありません。フィールドの
accessibleフラグの値に関係なく、ルックアップ・クラスのかわりにアクセス・チェックがただちに実行されます。フィールドが静的であり、戻されたVarHandleが操作されている場合は、フィールドの宣言クラスがまだ初期化されていない場合は初期化されます。
返されたVarHandleの特定のアクセス・モードは、次の条件ではサポートされません:
- フィールドが
finalと宣言されている場合、書込み、アトミック・アップデート、数値アトミック・アップデートおよびビット単位アトミック・アップデート・アクセス・モードはサポートされていません。 - フィールド・タイプが
byte,short,char,int,long,floatまたはdouble以外の場合、数値アトミック更新アクセス・モードはサポートされていません。 - フィールド・タイプが
boolean,byte,short,char,intまたはlong以外の場合、ビット単位のアトミック更新アクセス・モードはサポートされていません。
フィールドが
volatileと宣言されている場合、返されたVarHandleは、指定されたアクセス・モードに従って、フィールド(volatile宣言を効果的に無視)へのアクセスをオーバーライドします。フィールド型が
floatまたはdoubleの場合、数値およびアトミック更新アクセス・モードはビット単位の表現(それぞれFloat.floatToRawIntBits(float)とDouble.doubleToRawLongBits(double)を参照してください)を使用して値を比較します。- APIのノート:
- 数値およびアトミック更新アクセス・モードで実行される
float値またはdouble値のビット単位比較は、プリミティブ==演算子およびFloat.equals(java.lang.Object)およびDouble.equals(java.lang.Object)メソッドとは異なります。特に、NaN値の比較または-0.0と+0.0の比較については異なります。 この操作が予期せず失敗する可能性があるため、これらの値との比較および設定または比較および交換操作の実行時には注意が必要です。 JavaではNaNとみなされるNaN値は多数ありますが、Javaで提供されるIEEE 754浮動小数点演算では区別できません。 予期される値または証人値がNaN値で、(おそらくプラットフォーム固有の方法で)を別のNaN値に変換し、異なるビット単位の表現(詳細はFloat.intBitsToFloat(int)またはDouble.longBitsToDouble(long)を参照してください)を持つ場合、操作の失敗が発生する可能性があります。 値-0.0および+0.0は、ビット単位の表現は異なりますが、プリミティブ==演算子を使用するときは等しいとみなされます。 たとえば、数値アルゴリズムが予期される値を-0.0と計算し、以前に証人値を+0.0と計算した場合、操作の失敗が発生する可能性があります。 - パラメータ:
f-T型のフィールドとR型の宣言クラスを持つ、反映されたフィールド- 戻り値:
- 非静的フィールドまたは静的フィールドにアクセスするためのVarHandle
- スロー:
IllegalAccessException- アクセス・チェックが失敗した場合NullPointerException- 引数がnullの場合- 導入されたバージョン:
- 9
- フィールドが
-
revealDirect
public MethodHandleInfo revealDirect(MethodHandle target) この参照オブジェクトまたは類似のオブジェクトによって作成された直接メソッド・ハンドルを解読します。 このルックアップ・オブジェクトがターゲット・メソッド・ハンドルを再作成できるように、セキュリティおよびアクセス・チェックが実行されます。 これは、ターゲットが直接メソッド・ハンドルであるけれども、関連しないルックアップ・オブジェクトによって作成された場合は、解決が失敗する可能性があることを意味します。 これは、メソッド・ハンドルが呼出し元依存で、異なるクラスのルックアップ・オブジェクトによって作成された場合に発生する可能性があります。- パラメータ:
target- シンボリック参照コンポーネントに解決する直接メソッド・ハンドル- 戻り値:
- このルックアップ・オブジェクトからこのメソッド・ハンドルを再構築するために使用できるシンボリック参照
- スロー:
IllegalArgumentException- ターゲットが直接メソッド・ハンドルでない場合、またはアクセス・チェックが失敗した場合NullPointerException- ターゲットがnullの場合- 導入されたバージョン:
- 1.8
- 関連項目:
-
hasPrivateAccess
@Deprecated(since="14") public boolean hasPrivateAccess()非推奨。このメソッドは、当初は、完全な権限アクセスを意味するPRIVATEアクセスをテストするように設計されましたが、MODULEアクセスはPRIVATEアクセスから独立しているためです。hasFullPrivilegeAccess()を呼び出すことをお薦めします。この参照にPRIVATEおよびMODULEアクセス権がある場合はtrueを返します。- 戻り値:
- この参照に
PRIVATEおよびMODULEアクセス権がある場合、true。 - 導入されたバージョン:
- 9
-
hasFullPrivilegeAccess
public boolean hasFullPrivilegeAccess()この参照にPRIVATEおよびMODULEアクセス権などの「完全な権限アクセス」がある場合、trueを返します。 「ルックアップ・クラス」にアクセス可能なすべてのメンバーにアクセスするには、Lookupオブジェクトへの完全なアクセス権限が必要です。- 戻り値:
- この参照に完全な権限アクセスがある場合、
true。 - 導入されたバージョン:
- 14
- 関連項目:
-
PRIVATEアクセスをテストするように設計されましたが、MODULEアクセスはPRIVATEアクセスから独立しているためです。