public static final class MethodHandles.Lookup extends Object
メソッドハンドルを作成する必要のあるルックアップクラスは、MethodHandles.lookup
を呼び出して自分用のファクトリを作成します。Lookup
ファクトリオブジェクトの作成時には、ルックアップクラスのアイデンティティーが決定され、その情報が Lookup
オブジェクト内にセキュアに格納されます。その後、ルックアップクラス (またはその委譲先) は、Lookup
オブジェクトのファクトリメソッドを使ってアクセスチェックされたメンバーのメソッドハンドルを作成できます。これには、ルックアップクラスに許可されるメソッド、コンストラクタ、およびフィールドがすべて含まれます (private のものも含む)。
Lookup
オブジェクトのファクトリメソッドは、メソッド、コンストラクタ、およびフィールドのすべてのメジャーなユースケースに対応しています。これらのファクトリメソッドと、結果となるメソッドハンドルの動作との対応関係のサマリーを、次に示します。
ここで、型
lookup expression member behavior lookup.findGetter(C.class,"f",FT.class) FT f; (T) this.f; lookup.findStaticGetter(C.class,"f",FT.class) static
FT f;(T) C.f; lookup.findSetter(C.class,"f",FT.class) FT f; this.f = x; lookup.findStaticSetter(C.class,"f",FT.class) static
FT f;C.f = arg; lookup.findVirtual(C.class,"m",MT) T m(A*); (T) this.m(arg*); lookup.findStatic(C.class,"m",MT) static
T 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*); (T) 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.unreflect(aMethod) (static)?
T m(A*);(T) aMethod.invoke(thisOrNull, arg*); C
はメンバーの検索先となるクラスまたはインタフェースであり、各ルックアップメソッドでは refc
という名前のパラメータとしてドキュメント化されています。メソッドまたはコンストラクタの型 MT
は、戻り値の型 T
と一連の引数の型 A*
から構成されます。MT
とフィールドの型 FT
はどちらも、type
という名前のパラメータとしてドキュメント化されています。仮パラメータ this
は C
型の自己参照を表しています。これは、存在する場合は常にメソッドハンドル呼び出しの先頭の引数になります。(一部の protected
メンバーでは、this
の型がルックアップクラスに制限される場合があります。下記を参照してください。)名前 arg
は、メソッドハンドルのほかのすべての引数を表しています。Core Reflection API のコード例に含まれる名前 thisOrNull
は、アクセス対象のメソッドやフィールドが static の場合は null 参照を表し、それ以外の場合は this
を表します。名前 aMethod
、aField
、および aConstructor
は、指定されたメンバーに対応するリフレクションオブジェクトを表しています。
指定されたメンバーが可変引数 (つまりメソッドまたはコンストラクタ) の場合、返されるメソッドハンドルも可変引数になります。その他のすべての場合、返されるメソッドハンドルは固定引数になります。
ルックアップされたメソッドハンドルとベースとなるクラスメンバーとの等価性が、いくつかの場合に崩れる可能性があります。
C
がルックアップクラスのローダーからシンボルでアクセスできない場合でも、ルックアップが成功することがあります (同等の Java 式やバイトコード定数が存在しない場合でも)。
T
または MT
がルックアップクラスのローダーからシンボルでアクセスできない場合でも、ルックアップが成功することがあります。たとえば、MethodHandle.invokeExact
や MethodHandle.invoke
のルックアップは、要求された型とは無関係に常に成功します。
ldc
命令はセキュリティーマネージャーによるチェックの対象外です。
Lookup
のファクトリメソッド内で適用されます。これが、Core Reflection API との重要な違いです (java.lang.reflect.Method.invoke
ではすべての呼び出しで、すべての呼び出し元に対してアクセスチェックが実行される)。
すべてのアクセスチェックは Lookup
オブジェクトから始まりますが、このオブジェクトでは、記録されているルックアップクラスとすべてのメソッドハンドル作成要求とが照合されます。単一の Lookup
オブジェクトを使って任意の数のアクセスチェック済みメソッドハンドルを作成できます (すべては単一のルックアップクラスに基づいてチェックされる)。
Lookup
オブジェクトは、ほかの信頼できるコード (メタオブジェクトプロトコルなど) と共有できます。共有 Lookup
オブジェクトは、メソッドハンドルを作成する機能を、ルックアップクラスの private メンバーに委譲します。特権付きコードが Lookup
オブジェクトを使用する場合でも、アクセスチェックは元のルックアップクラスの特権に限定されます。
ルックアップが失敗する理由としては、包含しているクラスにルックアップクラスからアクセスできない、目的のクラスメンバーが見つからない、目的のクラスメンバーにルックアップクラスからアクセスできない、などが挙げられます。いずれの場合も、試みられたルックアップから ReflectiveOperationException
がスローされます。具体的なクラスは次のいずれかになります。
一般に、メソッド M
のメソッドハンドルをルックアップできる条件は、ルックアップクラスが M
の呼び出しをコンパイルして解決できる条件とまったく同じです。また、ルックアップの結果として得られたメソッドハンドルを呼び出す効果は、コンパイル済みで解決済みのM
呼び出しを実行する場合とまったく同じです。フィールドとコンストラクタについても同じことが言えます。
目的のメンバーが protected
である場合、ルックアップクラスが目的のメンバーと同じパッケージに含まれているか、そのメンバーを継承している必要があるという要件など、通常の JVM 規則が適用されます。(『Java Virtual Machine Specification』のセクション 4.9.2、5.4.3.5、および 6.4 を参照してください。)また、目的のメンバーが別のパッケージ内にある非 static フィールドまたはメソッドである場合、結果となるメソッドハンドルはルックアップクラスまたはそのいずれかのサブクラスのオブジェクトにしか適用されない可能性があります。この要件は、先頭の this
パラメータの型を C
(必ずルックアップクラスのスーパークラスになる) からルックアップクラス自体にナロー変換することで強制されます。
場合によっては、ネストされたクラス間のアクセスは、Java コンパイラが、別のクラスの private メソッドにアクセスするためのラッパーメソッドを同じトップレベルの宣言内で作成することによって得られます。たとえば、ネストされたクラス C.D
はほかの関連クラス (C
、C.D.E
、C.B
など) の内部の private メンバーにアクセスできますが、Java コンパイラがそれらの関連クラス内でラッパーメソッドを生成しなければいけない可能性があります。そのような場合、C.E
の Lookup
オブジェクトはそれらの private メンバーにアクセスできません。この制限の回避方法の 1 つが Lookup.in
メソッドであり、これを使うことで、特権レベルを特別に上げることなく C.E
のルックアップをそうしたほかのクラスのいずれかのルックアップに変換できます。
バイトコード命令は関連クラスローダー内のクラスしか参照できませんが、この API では、Class
オブジェクトへの参照が使用可能であるかぎり、任意のクラス内のメソッドを検索できます。そのようなクロスローダー参照は、Core Reflection API でも可能ですが、invokestatic
や getfield
などのバイトコード命令では不可能です。アプリケーション内でそのようなクロスローダー参照をチェックできるようにするためのセキュリティーマネージャー API が存在します。それらのチェックは、MethodHandles.Lookup
API と (Class
上に存在する) Core Reflection API の両方に適用されます。
アクセスチェックが適用されるのは、リフレクトされた名前付きのメソッド、コンストラクタ、およびフィールドに対してだけです。MethodHandle.asType
など、ほかのメソッドハンドル作成メソッドではアクセスチェックは一切不要であり、どの Lookup
オブジェクトとも無関係に MethodHandles
の static メソッドを使って行われます。
SecurityException
をスローすることでアクセスを拒否できます。smgr
をセキュリティーマネージャー、refc
をメンバーの検索先となる包含クラス、defc
をメンバーが実際に定義されているクラスと定義します。次の規則に従って呼び出しが行われます。
smgr.checkMemberAccess(refc, Member.PUBLIC)
が呼び出されます。
refc
のクラスローダーと同じでもその上位クラスでもない場合、smgr.checkPackageAccess(refcPkg)
が呼び出されます (refcPkg
は refc
のパッケージ)。
smgr.checkMemberAccess(defc, Member.DECLARED)
が呼び出されます。(defc
は refc
と同じである可能性もあります。)このセキュリティーマネージャーメソッドのデフォルト実装は、スタックを検査してリフレクション要求 (findStatic
など) の最初の呼び出し元を判別し、そのリフレクション要求の発生元クラスのクラスローダーが defc
のクラスローダーと異なる場合に追加のアクセス権チェックを実行します。
defc
と refc
がそれぞれ異なるクラスローダー内に存在しており、かつルックアップクラスのクラスローダーが defc
のクラスローダーと同じでもその上位クラスでもない場合、smgr.checkPackageAccess(defcPkg)
が呼び出されます (defcPkg
は defc
のパッケージ)。
修飾子と型 | フィールドと説明 |
---|---|
static int |
PACKAGE
package アクセス (デフォルトアクセス) を表す単一ビットマスク (lookupModes の結果に寄与する可能性がある)。 |
static int |
PRIVATE
private アクセスを表す単一ビットマスク (lookupModes の結果に寄与する可能性がある)。 |
static int |
PROTECTED
protected アクセスを表す単一ビットマスク (lookupModes の結果に寄与する可能性がある)。 |
static int |
PUBLIC
public アクセスを表す単一ビットマスク (lookupModes の結果に寄与する可能性がある)。 |
修飾子と型 | メソッドと説明 |
---|---|
MethodHandle |
bind(Object receiver, String name, MethodType type)
非 static メソッドの早期バインドメソッドハンドルを生成します。
|
MethodHandle |
findConstructor(Class<?> refc, MethodType type)
指定された型のコンストラクタを使ってオブジェクトの作成と初期化を行うメソッドハンドルを生成します。
|
MethodHandle |
findGetter(Class<?> refc, String name, Class<?> type)
非 static フィールドに対する読み取りアクセスを提供するメソッドハンドルを生成します。
|
MethodHandle |
findSetter(Class<?> refc, String name, Class<?> type)
非 static フィールドに対する書き込みアクセスを提供するメソッドハンドルを生成します。
|
MethodHandle |
findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller)
caller の invokespecial 命令から呼び出された場合と同じ効果を持つ、仮想メソッドの早期バインドメソッドハンドルを生成します。 |
MethodHandle |
findStatic(Class<?> refc, String name, MethodType type)
static メソッドのメソッドハンドルを生成します。
|
MethodHandle |
findStaticGetter(Class<?> refc, String name, Class<?> type)
static フィールドに対する読み取りアクセスを提供するメソッドハンドルを生成します。
|
MethodHandle |
findStaticSetter(Class<?> refc, String name, Class<?> type)
static フィールドに対する書き込みアクセスを提供するメソッドハンドルを生成します。
|
MethodHandle |
findVirtual(Class<?> refc, String name, MethodType type)
仮想メソッドのメソッドハンドルを生成します。
|
MethodHandles.Lookup |
in(Class<?> requestedLookupClass)
指定された新しいルックアップクラスでルックアップを作成します。
|
Class<?> |
lookupClass()
ルックアップを実行しているクラスを示します。
|
int |
lookupModes()
このルックアップオブジェクトがどのアクセス保護クラスのメンバーを生成できるかを示します。
|
String |
toString()
ルックアップの実行元となるクラスの名前を表示します。
|
MethodHandle |
unreflect(Method m)
ルックアップクラスがアクセス権を持つ場合に m への直接メソッドハンドルを作成します。
|
MethodHandle |
unreflectConstructor(Constructor c)
リフレクトされたコンストラクタのメソッドハンドルを生成します。
|
MethodHandle |
unreflectGetter(Field f)
リフレクトされたフィールドに対する読み取りアクセスを提供するメソッドハンドルを生成します。
|
MethodHandle |
unreflectSetter(Field f)
リフレクトされたフィールドに対する書き込みアクセスを提供するメソッドハンドルを生成します。
|
MethodHandle |
unreflectSpecial(Method m, Class<?> specialCaller)
リフレクトされたメソッドのメソッドハンドルを生成します。
|
public static final int PUBLIC
public static final int PRIVATE
public static final int PROTECTED
public static final int PACKAGE
package
アクセス (デフォルトアクセス) を表す単一ビットマスク (lookupModes
の結果に寄与する可能性がある)。値は 0x08
ですが、これは、特定のどの修飾子ビットにも、意味のあるかたちでは対応しません。public Class<?> lookupClass()
このクラスは最大レベルのアクセス権を暗黙的に示しますが、非 public メンバーにアクセスできるかどうかを制御するビットマスク lookupModes
により、アクセス権がさらに制限される可能性もあります。
public int lookupModes()
呼び出し元のクラス上で新しく作成されたルックアップオブジェクトでは、存在するすべてのビットが設定されますが、これは、呼び出し元のクラスは自身のすべてのメンバーにアクセスできるからです。以前のルックアップオブジェクトから作成された新しいルックアップクラス上のルックアップオブジェクトでは、いくつかのモードビットがゼロに設定されている可能性があります。その目的は、新しいルックアップオブジェクト経由でのアクセスを制限し、元のルックアップオブジェクトと新しいルックアップクラスの両方から到達可能な名前だけにアクセスできるようにすることです。
public MethodHandles.Lookup in(Class<?> requestedLookupClass)
lookupClass
として報告します。
ただし、結果となる Lookup
オブジェクトは、元のオブジェクトと同等以下のアクセス機能しか持たないことが保証されます。具体的には、アクセス機能が次のように失われる可能性があります。
requestedLookupClass
- 新しいルックアップオブジェクト用に要求されるルックアップクラスNullPointerException
- 引数が null の場合public String toString()
Class.getName
から報告されるものです。) このルックアップに許可されるアクセスに制限がある場合、そのことを示すために、スラッシュとキーワードで構成される接尾辞がクラス名に追加されます。キーワードは許可される最強のアクセスを表しており、次のように選択されます。
MethodHandles.lookup
から取得されたオブジェクトの場合だけです。Lookup.in
で作成されたオブジェクトでは常にアクセスが制限され、接尾辞が表示されます。
(protected アクセスが private アクセスより強いというのは、奇妙に感じるかもしれません。package アクセスから独立して見た場合、protected アクセスが最初に失われるものになりますが、それは、呼び出し元と呼び出し先の間に直接的なサブクラス関係が必要になるからです。)
toString
、クラス: Object
in(java.lang.Class<?>)
public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
findVirtual
や findSpecial
のように、メソッドハンドルの型に追加のレシーバ引数が挿入されることはありません。) メソッドとそのすべての引数の型にルックアップクラスからアクセスできる必要があります。メソッドのクラスがまだ初期化されていない場合はそれが即時に実行され、そのあとでメソッドハンドルが返されます。
返されるメソッドハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
refc
- メソッドのアクセス元となるクラスname
- メソッドの名前type
- メソッドの型NoSuchMethodException
- メソッドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドが static
でない場合、あるいはメソッドの可変引数修飾子ビットが設定されて asVarargsCollector
が失敗した場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
refc
) を追加したものになります。メソッドとそのすべての引数の型にルックアップクラスからアクセスできる必要があります。
ハンドルは呼び出し時に、最初の引数をレシーバとみなし、そのレシーバの型でディスパッチしてどのメソッド実装に入るかを決定します。(このディスパッチアクションは、invokevirtual
または invokeinterface
命令によって実行されるアクションと同一です。)
ルックアップクラスがメンバーにアクセスする完全な権限を持っている場合、最初の引数の型は refc
になります。それ以外の場合、メンバーは protected
である必要があり、最初の引数の型はルックアップクラスに制限されます。
返されるメソッドハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
invokevirtual
命令と findVirtual
で生成されるメソッドハンドルは基本的に同等であるため、クラスが MethodHandle
で名前の文字列が invokeExact
または invoke
の場合、結果となるメソッドハンドルは、MethodHandles.exactInvoker
または MethodHandles.invoker
で同じ type
引数を指定して生成されたものと同等になります。
refc
- メソッドのアクセス元となるクラスまたはインタフェースname
- メソッドの名前type
- メソッドの型 (レシーバ引数は含まない)NoSuchMethodException
- メソッドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドが static
の場合、あるいはメソッドの可変引数修飾子ビットが設定されて asVarargsCollector
が失敗した場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException
注:要求する型の戻り値の型は void
でなければいけません。これは、JVM のコンストラクタ型記述子の扱いに準拠したものです。
返されるメソッドハンドルの引数が可変引数になるのは、コンストラクタの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
refc
- メソッドのアクセス元となるクラスまたはインタフェースtype
- メソッドの型 (レシーバ引数は含めず、戻り値の型は void にする)NoSuchMethodException
- コンストラクタが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていて asVarargsCollector
が失敗した場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException
caller
の invokespecial
命令から呼び出された場合と同じ効果を持つ、仮想メソッドの早期バインドメソッドハンドルを生成します。メソッドハンドルの型は、メソッドの型の先頭に、適切に制限されたレシーバの型 (caller
など) を追加したものになります。メソッドとそのすべての引数の型に呼び出し元からアクセスできる必要があります。
ハンドルは呼び出し時に、最初の引数をレシーバとみなしますが、そのレシーバの型でのディスパッチは行いません。(この直接呼び出しアクションは、invokespecial
命令によって実行されるアクションと同一です。)
明示的に指定された呼び出し元クラスがルックアップクラスと同一でない場合や、このルックアップオブジェクトが private アクセス特権を持たない場合は、アクセスが失敗します。
返されるメソッドハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
refc
- メソッドのアクセス元となるクラスまたはインタフェースname
- メソッドの名前 (「<init>」であってはいけない)type
- メソッドの型 (レシーバ引数は含まない)specialCaller
- invokespecial
を実行する、提案された呼び出し元クラスNoSuchMethodException
- メソッドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていて asVarargsCollector
が失敗した場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- メソッドのアクセス元となるクラスまたはインタフェースname
- フィールドの名前type
- フィールドの型NoSuchFieldException
- フィールドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはフィールドが static
の場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- メソッドのアクセス元となるクラスまたはインタフェースname
- フィールドの名前type
- フィールドの型NoSuchFieldException
- フィールドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはフィールドが static
の場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- メソッドのアクセス元となるクラスまたはインタフェースname
- フィールドの名前type
- フィールドの型NoSuchFieldException
- フィールドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはフィールドが static
でない場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- メソッドのアクセス元となるクラスまたはインタフェースname
- フィールドの名前type
- フィールドの型NoSuchFieldException
- フィールドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはフィールドが static
でない場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
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); MethodType mt1 = mh1.type(); if (mh0.isVarargsCollector()) mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1)); return mh1;
defc
は receiver.getClass()
またはそのクラスのスーパータイプのいずれかであり、その中では、要求されたメソッドにルックアップクラスからアクセスできます。(bindTo
は可変引数を保持しません。)receiver
- メソッドのアクセス元となるオブジェクトname
- メソッドの名前type
- メソッドの型 (レシーバ引数は含まない)NoSuchMethodException
- メソッドが存在しない場合IllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていて asVarargsCollector
が失敗した場合SecurityException
- セキュリティーマネージャーが存在し、それがアクセスを拒否した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle unreflect(Method m) throws IllegalAccessException
accessible
フラグが設定されていない場合、ルックアップクラスに代わって即座にアクセスチェックが実行されます。m が public でない場合、結果となるハンドルを信頼できない相手と共有しないでください。
返されるメソッドハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
m
- リフレクトされたメソッドIllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていて asVarargsCollector
が失敗した場合NullPointerException
- 引数が null の場合public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException
specialCaller
内から invokespecial
命令を実行した場合のように、レシーバでのメソッドオーバーライドのチェックをバイパスします。メソッドハンドルの型は、メソッドの型の先頭に、(メソッドのレシーバではなく) 特殊な呼び出し元の型を追加したものになります。メソッドの accessible
フラグが設定されていない場合、invokespecial
命令がリンクされていたかのように、ルックアップクラスに代わって即座にアクセスチェックが実行されます。
返されるメソッドハンドルの引数が可変引数になるのは、メソッドの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
m
- リフレクトされたメソッドspecialCaller
- メソッドを形式上呼び出すクラスIllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていて asVarargsCollector
が失敗した場合NullPointerException
- いずれかの引数が null の場合public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException
newInstance
操作を実行し、メソッドハンドルに渡された引数に基づいてコンストラクタのクラスの新しいインスタンスを作成します。
コンストラクタの accessible
フラグが設定されていない場合、ルックアップクラスに代わって即座にアクセスチェックが実行されます。
返されるメソッドハンドルの引数が可変引数になるのは、コンストラクタの可変引数修飾子ビット (0x0080
) が設定されている場合だけです。
c
- リフレクトされたコンストラクタIllegalAccessException
- アクセスチェックが失敗した場合、またはメソッドの可変引数修飾子ビットが設定されていて asVarargsCollector
が失敗した場合NullPointerException
- 引数が null の場合public MethodHandle unreflectGetter(Field f) throws IllegalAccessException
accessible
フラグが設定されていない場合、ルックアップクラスに代わって即座にアクセスチェックが実行されます。f
- リフレクトされたフィールドIllegalAccessException
- アクセスチェックが失敗した場合NullPointerException
- 引数が null の場合public MethodHandle unreflectSetter(Field f) throws IllegalAccessException
accessible
フラグが設定されていない場合、ルックアップクラスに代わって即座にアクセスチェックが実行されます。f
- リフレクトされたフィールドIllegalAccessException
- アクセスチェックが失敗した場合NullPointerException
- 引数が null の場合 バグまたは機能を送信
詳細な API リファレンスおよび開発者ドキュメントについては、Java SE のドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.