MethodHandles.Lookup (Java SE 9 & JDK 9 ) (original) (raw)
- Enclosing class:
MethodHandles
public static final class MethodHandles.Lookup
extends Object
A lookup object is a factory for creating method handles, when the creation requires access checking. Method handles do not perform access checks when they are called, but rather when they are created. Therefore, method handle access restrictions must be enforced when a method handle is created. The caller class against which those restrictions are enforced is known as the lookup class.
A lookup class which needs to create method handles will callMethodHandles.lookup to create a factory for itself. When the Lookup
factory object is created, the identity of the lookup class is determined, and securely stored in the Lookup
object. The lookup class (or its delegates) may then use factory methods on the Lookup
object to create method handles for access-checked members. This includes all methods, constructors, and fields which are allowed to the lookup class, even private ones.
Lookup Factory Methods
The factory methods on a Lookup
object correspond to all major use cases for methods, constructors, and fields. Each method handle created by a factory method is the functional equivalent of a particular bytecode behavior. (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.) Here is a summary of the correspondence between these factory methods and the behavior of the resulting method handles:
lookup method behaviors
lookup expression | member | bytecode behavior |
---|---|---|
lookup.findGetter(C.class,"f",FT.class) | FT f; | (T) this.f; |
lookup.findStaticGetter(C.class,"f",FT.class) | staticFT f; | (T) 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.unreflect(aMethod) | (static)?T m(A*); | (T) aMethod.invoke(thisOrNull, arg*); |
lookup.findClass("C") | class C { ... } | C.class; |
Here, the type C is the class or interface being searched for a member, documented as a parameter named refc in the lookup methods. The method type MT is composed from the return type T and the sequence of argument types A* . The constructor also has a sequence of argument types A* and is deemed to return the newly-created object of type C . Both MT and the field type FT are documented as a parameter named type . The formal parameter this stands for the self-reference of type C ; if it is present, it is always the leading argument to the method handle invocation. (In the case of some protected members, this may be restricted in type to the lookup class; see below.) The name arg stands for all the other method handle arguments. In the code examples for the Core Reflection API, the name thisOrNull stands for a null reference if the accessed method or field is static, and this otherwise. The names aMethod , aField , and aConstructor stand for reflective objects corresponding to the given members. |
||
The bytecode behavior for a findClass operation is a load of a constant class, as if by ldc CONSTANT_Class . The behavior is represented, not as a method handle, but directly as a Class constant. |
||
In cases where the given member is of variable arity (i.e., a method or constructor) the returned method handle will also be of variable arity. In all other cases, the returned method handle will be of fixed arity. | ||
Discussion: The equivalence between looked-up method handles and underlying class members and bytecode behaviors can break down in a few ways: |
- If
C
is not symbolically accessible from the lookup class's loader, the lookup can still succeed, even when there is no equivalent Java expression or bytecoded constant. - Likewise, if
T
orMT
is not symbolically accessible from the lookup class's loader, the lookup can still succeed. For example, lookups forMethodHandle.invokeExact
andMethodHandle.invoke
will always succeed, regardless of requested type. - If there is a security manager installed, it can forbid the lookup on various grounds (see below). By contrast, the
ldc
instruction on aCONSTANT_MethodHandle
constant is not subject to security manager checks. - If the looked-up method has avery large arity, the method handle creation may fail, due to the method handle type having too many parameters.
Access checking
Access checks are applied in the factory methods of Lookup
, when a method handle is created. This is a key difference from the Core Reflection API, sincejava.lang.reflect.Method.invoke performs access checking against every caller, on every call.
All access checks start from a Lookup
object, which compares its recorded lookup class against all requests to create method handles. A single Lookup
object can be used to create any number of access-checked method handles, all checked against a single lookup class.
A Lookup
object can be shared with other trusted code, such as a metaobject protocol. A shared Lookup
object delegates the capability to create method handles on private members of the lookup class. Even if privileged code uses the Lookup
object, the access checking is confined to the privileges of the original lookup class.
A lookup can fail, because the containing class is not accessible to the lookup class, or because the desired class member is missing, or because the desired class member is not accessible to the lookup class, or because the lookup object is not trusted enough to access the member. In any of these cases, a ReflectiveOperationException
will be thrown from the attempted lookup. The exact class will be one of the following:
- NoSuchMethodException — if a method is requested but does not exist
- NoSuchFieldException — if a field is requested but does not exist
- IllegalAccessException — if the member exists but an access check fails
In general, the conditions under which a method handle may be looked up for a methodM
are no more restrictive than the conditions under which the lookup class could have compiled, verified, and resolved a call toM
. Where the JVM would raise exceptions likeNoSuchMethodError
, a method handle lookup will generally raise a corresponding checked exception, such asNoSuchMethodException
. And the effect of invoking the method handle resulting from the lookup is exactly equivalent to executing the compiled, verified, and resolved call toM
. The same point is true of fields and constructors.
Discussion: Access checks only apply to named and reflected methods, constructors, and fields. Other method handle creation methods, such asMethodHandle.asType, do not require any access checks, and are used independently of anyLookup
object.
If the desired member isprotected
, the usual JVM rules apply, including the requirement that the lookup class must be either be in the same package as the desired member, or must inherit that member. (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.) In addition, if the desired member is a non-static field or method in a different package, the resulting method handle may only be applied to objects of the lookup class or one of its subclasses. This requirement is enforced by narrowing the type of the leadingthis
parameter fromC
(which will necessarily be a superclass of the lookup class) to the lookup class itself.
The JVM imposes a similar requirement oninvokespecial
instruction, that the receiver argument must match both the resolved method and the current class. Again, this requirement is enforced by narrowing the type of the leading parameter to the resulting method handle. (See the Java Virtual Machine Specification, section 4.10.1.9.)
The JVM represents constructors and static initializer blocks as internal methods with special names ("<init>"
and"<clinit>"
). The internal syntax of invocation instructions allows them to refer to such internal methods as if they were normal methods, but the JVM bytecode verifier rejects them. A lookup of such an internal method will produce aNoSuchMethodException
.
In some cases, access between nested classes is obtained by the Java compiler by creating an wrapper method to access a private method of another class in the same top-level declaration. For example, a nested classC.D
can access private members within other related classes such asC
,C.D.E
, orC.B
, but the Java compiler may need to generate wrapper methods in those related classes. In such cases, aLookup
object onC.E
would be unable to those private members. A workaround for this limitation is the Lookup.in method, which can transform a lookup onC.E
into one on any of those other classes, without special elevation of privilege.
The accesses permitted to a given lookup object may be limited, according to its set of lookupModes, to a subset of members normally accessible to the lookup class. For example, the publicLookup method produces a lookup object which is only allowed to access public members in public classes of exported packages. The caller sensitive method lookup produces a lookup object with full capabilities relative to its caller class, to emulate all supported bytecode behaviors. Also, the Lookup.in method may produce a lookup object with fewer access modes than the original lookup object.
Discussion of private access: We say that a lookup has private access if its lookup modes include the possibility of accessingprivate
members. As documented in the relevant methods elsewhere, only lookups with private access possess the following capabilities: - access private fields, methods, and constructors of the lookup class
- create method handles which invoke caller sensitive methods, such as
Class.forName
- create method handles which emulate invokespecial instructions
- avoid package access checks for classes accessible to the lookup class
- create delegated lookup objects which have private access to other classes within the same package member
Each of these permissions is a consequence of the fact that a lookup object with private access can be securely traced back to an originating class, whose bytecode behaviors and Java language access permissions can be reliably determined and emulated by method handles.
Security manager interactions
Although bytecode instructions can only refer to classes in a related class loader, this API can search for methods in any class, as long as a reference to its Class
object is available. Such cross-loader references are also possible with the Core Reflection API, and are impossible to bytecode instructions such as invokestatic
or getfield
. There is a security manager API to allow applications to check such cross-loader references. These checks apply to both the MethodHandles.Lookup
API and the Core Reflection API (as found on Class).
If a security manager is present, member and class lookups are subject to additional checks. From one to three calls are made to the security manager. Any of these calls can refuse access by throwing aSecurityException. Define smgr
as the security manager,lookc
as the lookup class of the current lookup object,refc
as the containing class in which the member is being sought, and defc
as the class in which the member is actually defined. (If a class or other type is being accessed, the refc
and defc
values are the class itself.) The value lookc
is defined as not present if the current lookup object does not haveprivate access. The calls are made according to the following rules:
- Step 1: If
lookc
is not present, or if its class loader is not the same as or an ancestor of the class loader ofrefc
, then smgr.checkPackageAccess(refcPkg) is called, whererefcPkg
is the package ofrefc
. - Step 2a: If the retrieved member is not public and
lookc
is not present, thensmgr.checkPermission withRuntimePermission("accessDeclaredMembers")
is called. - Step 2b: If the retrieved class has a
null
class loader, andlookc
is not present, thensmgr.checkPermission withRuntimePermission("getClassLoader")
is called. - Step 3: If the retrieved member is not public, and if
lookc
is not present, and ifdefc
andrefc
are different, then smgr.checkPackageAccess(defcPkg) is called, wheredefcPkg
is the package ofdefc
.
Security checks are performed after other access checks have passed. Therefore, the above rules presuppose a member or class that is public, or else that is being accessed from a lookup class that has rights to access the member or class.
Caller sensitive methods
A small number of Java methods have a special property called caller sensitivity. A caller-sensitive method can behave differently depending on the identity of its immediate caller.
If a method handle for a caller-sensitive method is requested, the general rules for bytecode behaviors apply, but they take account of the lookup class in a special way. The resulting method handle behaves as if it were called from an instruction contained in the lookup class, so that the caller-sensitive method detects the lookup class. (By contrast, the invoker of the method handle is disregarded.) Thus, in the case of caller-sensitive methods, different lookup classes may give rise to differently behaving method handles.
In cases where the lookup object ispublicLookup(), or some other lookup object withoutprivate access, the lookup class is disregarded. In such cases, no caller-sensitive method handle can be created, access is forbidden, and the lookup fails with anIllegalAccessException
.
Discussion: For example, the caller-sensitive methodClass.forName(x) can return varying classes or throw varying exceptions, depending on the class loader of the class that calls it. A public lookup of Class.forName
will fail, because there is no reasonable way to determine its bytecode behavior.
If an application caches method handles for broad sharing, it should use publicLookup()
to create them. If there is a lookup of Class.forName
, it will fail, and the application must take appropriate action in that case. It may be that a later lookup, perhaps during the invocation of a bootstrap method, can incorporate the specific identity of the caller, making the method accessible.
The function MethodHandles.lookup
is caller sensitive so that there can be a secure foundation for lookups. Nearly all other methods in the JSR 292 API rely on lookup objects to check access requests.
Field Detail
* #### PUBLIC public static final int PUBLIC A single-bit mask representing `public` access, which may contribute to the result of [lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). The value, `0x01`, happens to be the same as the value of the`public` [modifier bit](../../../java/lang/reflect/Modifier.html#PUBLIC). See Also: [Constant Field Values](../../../constant-values.html#java.lang.invoke.MethodHandles.Lookup.PUBLIC) * #### PRIVATE public static final int PRIVATE A single-bit mask representing `private` access, which may contribute to the result of [lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). The value, `0x02`, happens to be the same as the value of the`private` [modifier bit](../../../java/lang/reflect/Modifier.html#PRIVATE). See Also: [Constant Field Values](../../../constant-values.html#java.lang.invoke.MethodHandles.Lookup.PRIVATE) * #### PROTECTED public static final int PROTECTED A single-bit mask representing `protected` access, which may contribute to the result of [lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). The value, `0x04`, happens to be the same as the value of the`protected` [modifier bit](../../../java/lang/reflect/Modifier.html#PROTECTED). See Also: [Constant Field Values](../../../constant-values.html#java.lang.invoke.MethodHandles.Lookup.PROTECTED) * #### PACKAGE public static final int PACKAGE A single-bit mask representing `package` access (default access), which may contribute to the result of [lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). The value is `0x08`, which does not correspond meaningfully to any particular [modifier bit](../../../java/lang/reflect/Modifier.html "class in java.lang.reflect"). See Also: [Constant Field Values](../../../constant-values.html#java.lang.invoke.MethodHandles.Lookup.PACKAGE) * #### MODULE public static final int MODULE A single-bit mask representing `module` access (default access), which may contribute to the result of [lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). The value is `0x10`, which does not correspond meaningfully to any particular [modifier bit](../../../java/lang/reflect/Modifier.html "class in java.lang.reflect"). In conjunction with the `PUBLIC` modifier bit, a `Lookup` with this lookup mode can access all public types in the module of the lookup class and public types in packages exported by other modules to the module of the lookup class. Since: 9 See Also: [Constant Field Values](../../../constant-values.html#java.lang.invoke.MethodHandles.Lookup.MODULE) * #### UNCONDITIONAL public static final int UNCONDITIONAL A single-bit mask representing `unconditional` access which may contribute to the result of [lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). The value is `0x20`, which does not correspond meaningfully to any particular [modifier bit](../../../java/lang/reflect/Modifier.html "class in java.lang.reflect"). A `Lookup` with this lookup mode assumes [readability](../../../java/lang/Module.html#canRead-java.lang.Module-). In conjunction with the `PUBLIC` modifier bit, a `Lookup` with this lookup mode can access all public members of public types of all modules where the type is in a package that is [exported unconditionally](../../../java/lang/Module.html#isExported-java.lang.String-). Since: 9 See Also: [MethodHandles.publicLookup()](../../../java/lang/invoke/MethodHandles.html#publicLookup--), [Constant Field Values](../../../constant-values.html#java.lang.invoke.MethodHandles.Lookup.UNCONDITIONAL)
Method Detail
* #### lookupClass public [Class](../../../java/lang/Class.html "class in java.lang")<?> lookupClass() Tells which class is performing the lookup. It is this class against which checks are performed for visibility and access permissions. The class implies a maximum level of access permission, but the permissions may be additionally limited by the bitmask[lookupModes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--), which controls whether non-public members can be accessed. Returns: the lookup class, on behalf of which this lookup object finds members * #### lookupModes public int lookupModes() Tells which access-protection classes of members this lookup object can produce. The result is a bit-mask of the bits[PUBLIC (0x01)](../../../java/lang/invoke/MethodHandles.Lookup.html#PUBLIC),[PRIVATE (0x02)](../../../java/lang/invoke/MethodHandles.Lookup.html#PRIVATE),[PROTECTED (0x04)](../../../java/lang/invoke/MethodHandles.Lookup.html#PROTECTED),[PACKAGE (0x08)](../../../java/lang/invoke/MethodHandles.Lookup.html#PACKAGE),[MODULE (0x10)](../../../java/lang/invoke/MethodHandles.Lookup.html#MODULE), and [UNCONDITIONAL (0x20)](../../../java/lang/invoke/MethodHandles.Lookup.html#UNCONDITIONAL). A freshly-created lookup object on the [caller's class](../../../java/lang/invoke/MethodHandles.html#lookup--) has all possible bits set, except `UNCONDITIONAL`. The lookup can be used to access all members of the caller's class, all public types in the caller's module, and all public types in packages exported by other modules to the caller's module. A lookup object on a new lookup class[created from a previous lookup object](../../../java/lang/invoke/MethodHandles.Lookup.html#in-java.lang.Class-) may have some mode bits set to zero. Mode bits can also be[directly cleared](../../../java/lang/invoke/MethodHandles.Lookup.html#dropLookupMode-int-). Once cleared, mode bits cannot be restored from the downgraded lookup object. The purpose of this is to restrict access via the new lookup object, so that it can access only names which can be reached by the original lookup object, and also by the new lookup class. Returns: the lookup modes, which limit the kinds of access performed by this lookup object See Also: [in(java.lang.Class<?>)](../../../java/lang/invoke/MethodHandles.Lookup.html#in-java.lang.Class-), [dropLookupMode(int)](../../../java/lang/invoke/MethodHandles.Lookup.html#dropLookupMode-int-) * #### in public [MethodHandles.Lookup](../../../java/lang/invoke/MethodHandles.Lookup.html "class in java.lang.invoke") in([Class](../../../java/lang/Class.html "class in java.lang")<?> requestedLookupClass) Creates a lookup on the specified new lookup class. The resulting object will report the specified class as its own [lookupClass](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupClass). However, the resulting `Lookup` object is guaranteed to have no more access capabilities than the original. In particular, access capabilities can be lost as follows: * If the old lookup class is in a [named](../../../java/lang/Module.html#isNamed--) module, and the new lookup class is in a different module `M`, then no members, not even public members in `M`'s exported packages, will be accessible. The exception to this is when this lookup is [publicLookup](../../../java/lang/invoke/MethodHandles.html#publicLookup--), in which case `PUBLIC` access is not lost. * If the old lookup class is in an unnamed module, and the new lookup class is a different module then [MODULE](../../../java/lang/invoke/MethodHandles.Lookup.html#MODULE) access is lost. * If the new lookup class differs from the old one then `UNCONDITIONAL` is lost. * If the new lookup class is in a different package than the old one, protected and default (package) members will not be accessible. * If the new lookup class is not within the same package member as the old one, private members will not be accessible, and protected members will not be accessible by virtue of inheritance. (Protected members may continue to be accessible because of package sharing.) * If the new lookup class is not accessible to the old lookup class, then no members, not even public members, will be accessible. (In all other cases, public members will continue to be accessible.) The resulting lookup's capabilities for loading classes (used during [findClass(java.lang.String)](../../../java/lang/invoke/MethodHandles.Lookup.html#findClass-java.lang.String-) invocations) are determined by the lookup class' loader, which may change due to this operation. Parameters: `requestedLookupClass` \- the desired lookup class for the new lookup object Returns: a lookup object which reports the desired lookup class, or the same object if there is no change Throws: `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the argument is null * #### dropLookupMode public [MethodHandles.Lookup](../../../java/lang/invoke/MethodHandles.Lookup.html "class in java.lang.invoke") dropLookupMode(int modeToDrop) Creates a lookup on the same lookup class which this lookup object finds members, but with a lookup mode that has lost the given lookup mode. The lookup mode to drop is one of [PUBLIC](../../../java/lang/invoke/MethodHandles.Lookup.html#PUBLIC), [MODULE](../../../java/lang/invoke/MethodHandles.Lookup.html#MODULE), [PACKAGE](../../../java/lang/invoke/MethodHandles.Lookup.html#PACKAGE), [PROTECTED](../../../java/lang/invoke/MethodHandles.Lookup.html#PROTECTED) or [PRIVATE](../../../java/lang/invoke/MethodHandles.Lookup.html#PRIVATE).[PROTECTED](../../../java/lang/invoke/MethodHandles.Lookup.html#PROTECTED) and [UNCONDITIONAL](../../../java/lang/invoke/MethodHandles.Lookup.html#UNCONDITIONAL) are always dropped and so the resulting lookup mode will never have these access capabilities. When dropping `PACKAGE` then the resulting lookup will not have `PACKAGE` or `PRIVATE` access. When dropping `MODULE` then the resulting lookup will not have `MODULE`, `PACKAGE`, or `PRIVATE` access. If `PUBLIC` is dropped then the resulting lookup has no access. Parameters: `modeToDrop` \- the lookup mode to drop Returns: a lookup object which lacks the indicated mode, or the same object if there is no change Throws: `[IllegalArgumentException](../../../java/lang/IllegalArgumentException.html "class in java.lang")` \- if `modeToDrop` is not one of `PUBLIC`,`MODULE`, `PACKAGE`, `PROTECTED`, `PRIVATE` or `UNCONDITIONAL` Since: 9 See Also: [MethodHandles.privateLookupIn(java.lang.Class<?>, java.lang.invoke.MethodHandles.Lookup)](../../../java/lang/invoke/MethodHandles.html#privateLookupIn-java.lang.Class-java.lang.invoke.MethodHandles.Lookup-) * #### defineClass public [Class](../../../java/lang/Class.html "class in java.lang")<?> defineClass(byte[] bytes) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Defines a class to the same class loader and in the same runtime package and[protection domain](../../../java/security/ProtectionDomain.html "class in java.security") as this lookup's[lookup class](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupClass--). The [lookup modes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--) for this lookup must include[PACKAGE](../../../java/lang/invoke/MethodHandles.Lookup.html#PACKAGE) access as default (package) members will be accessible to the class. The `PACKAGE` lookup mode serves to authenticate that the lookup object was created by a caller in the runtime package (or derived from a lookup originally created by suitably privileged code to a target class in the runtime package). The `bytes` parameter is the class bytes of a valid class file (as defined by the _The Java Virtual Machine Specification_) with a class name in the same package as the lookup class. This method does not run the class initializer. The class initializer may run at a later time, as detailed in section 12.4 of the _The Java Language Specification_. If there is a security manager, its `checkPermission` method is first called to check `RuntimePermission("defineClass")`. Parameters: `bytes` \- the class bytes Returns: the `Class` object for the class Throws: `[IllegalArgumentException](../../../java/lang/IllegalArgumentException.html "class in java.lang")` \- the bytes are for a class in a different package to the lookup class `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if this lookup does not have `PACKAGE` access `[LinkageError](../../../java/lang/LinkageError.html "class in java.lang")` \- if the class is malformed (`ClassFormatError`), cannot be verified (`VerifyError`), is already defined, or another linkage error occurs `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if denied by the security manager `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if `bytes` is `null` Since: 9 See Also: [MethodHandles.privateLookupIn(java.lang.Class<?>, java.lang.invoke.MethodHandles.Lookup)](../../../java/lang/invoke/MethodHandles.html#privateLookupIn-java.lang.Class-java.lang.invoke.MethodHandles.Lookup-), [dropLookupMode(int)](../../../java/lang/invoke/MethodHandles.Lookup.html#dropLookupMode-int-), [ClassLoader.defineClass(String,byte\[\],int,int,ProtectionDomain)](../../../java/lang/ClassLoader.html#defineClass-java.lang.String-byte:A-int-int-java.security.ProtectionDomain-) * #### toString public [String](../../../java/lang/String.html "class in java.lang") toString() Displays the name of the class from which lookups are to be made. (The name is the one reported by [Class.getName](../../../java/lang/Class.html#getName--).) If there are restrictions on the access permitted to this lookup, this is indicated by adding a suffix to the class name, consisting of a slash and a keyword. The keyword represents the strongest allowed access, and is chosen as follows: * If no access is allowed, the suffix is "/noaccess". * If only public access to types in exported packages is allowed, the suffix is "/public". * If only public access and unconditional access are allowed, the suffix is "/publicLookup". * If only public and module access are allowed, the suffix is "/module". * If only public, module and package access are allowed, the suffix is "/package". * If only public, module, package, and private access are allowed, the suffix is "/private". If none of the above cases apply, it is the case that full access (public, module, package, private, and protected) is allowed. In this case, no suffix is added. This is true only of an object obtained originally from[MethodHandles.lookup](../../../java/lang/invoke/MethodHandles.html#lookup--). Objects created by [Lookup.in](../../../java/lang/invoke/MethodHandles.Lookup.html#in-java.lang.Class-) always have restricted access, and will display a suffix. (It may seem strange that protected access should be stronger than private access. Viewed independently from package access, protected access is the first to be lost, because it requires a direct subclass relationship between caller and callee.) Overrides: `[toString](../../../java/lang/Object.html#toString--)` in class `[Object](../../../java/lang/Object.html "class in java.lang")` Returns: a string representation of the object. See Also: [in(java.lang.Class<?>)](../../../java/lang/invoke/MethodHandles.Lookup.html#in-java.lang.Class-) * #### findStatic public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findStatic([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [MethodType](../../../java/lang/invoke/MethodType.html "class in java.lang.invoke") type) throws [NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle for a static method. The type of the method handle will be that of the method. (Since static methods do not take receivers, there is no additional receiver argument inserted into the method handle type, as there would be with [findVirtual](../../../java/lang/invoke/MethodHandles.Lookup.html#findVirtual-java.lang.Class-java.lang.String-java.lang.invoke.MethodType-) or [findSpecial](../../../java/lang/invoke/MethodHandles.Lookup.html#findSpecial-java.lang.Class-java.lang.String-java.lang.invoke.MethodType-java.lang.Class-).) The method and all its argument types must be accessible to the lookup object. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the method's variable arity modifier bit (`0x0080`) is set. If the returned method handle is invoked, the method's class will be initialized, if it has not already been initialized. **Example:** > ``` > > 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()); > > ``` Parameters: `refc` \- the class from which the method is accessed `name` \- the name of the method `type` \- the type of the method Returns: the desired method handle Throws: `[NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang")` \- if the method does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the method is not `static`, or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### findVirtual public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findVirtual([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [MethodType](../../../java/lang/invoke/MethodType.html "class in java.lang.invoke") type) throws [NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle for a virtual method. The type of the method handle will be that of the method, with the receiver type (usually `refc`) prepended. The method and all its argument types must be accessible to the lookup object. When called, the handle will treat the first argument as a receiver and dispatch on the receiver's type to determine which method implementation to enter. (The dispatching action is identical with that performed by an`invokevirtual` or `invokeinterface` instruction.) The first argument will be of type `refc` if the lookup class has full privileges to access the member. Otherwise the member must be `protected` and the first argument will be restricted in type to the lookup class. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the method's variable arity modifier bit (`0x0080`) is set. Because of the general [equivalence](MethodHandles.Lookup.html#equiv) between `invokevirtual` instructions and method handles produced by `findVirtual`, if the class is `MethodHandle` and the name string is`invokeExact` or `invoke`, the resulting method handle is equivalent to one produced by[MethodHandles.exactInvoker](../../../java/lang/invoke/MethodHandles.html#exactInvoker-java.lang.invoke.MethodType-) or[MethodHandles.invoker](../../../java/lang/invoke/MethodHandles.html#invoker-java.lang.invoke.MethodType-) with the same `type` argument. If the class is `VarHandle` and the name string corresponds to the name of a signature-polymorphic access mode method, the resulting method handle is equivalent to one produced by[MethodHandles.varHandleInvoker(java.lang.invoke.VarHandle.AccessMode, java.lang.invoke.MethodType)](../../../java/lang/invoke/MethodHandles.html#varHandleInvoker-java.lang.invoke.VarHandle.AccessMode-java.lang.invoke.MethodType-) with the access mode corresponding to the name string and with the same`type` arguments. **Example:** > ``` > > 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()); > > ``` Parameters: `refc` \- the class or interface from which the method is accessed `name` \- the name of the method `type` \- the type of the method, with the receiver argument omitted Returns: the desired method handle Throws: `[NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang")` \- if the method does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the method is `static`, or if the method is `private` method of interface, or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### findConstructor public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findConstructor([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [MethodType](../../../java/lang/invoke/MethodType.html "class in java.lang.invoke") type) throws [NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle which creates an object and initializes it, using the constructor of the specified type. The parameter types of the method handle will be those of the constructor, while the return type will be a reference to the constructor's class. The constructor and all its argument types must be accessible to the lookup object. The requested type must have a return type of `void`. (This is consistent with the JVM's treatment of constructor type descriptors.) The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the constructor's variable arity modifier bit (`0x0080`) is set. If the returned method handle is invoked, the constructor's class will be initialized, if it has not already been initialized. **Example:** > ``` > > 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()); > > ``` Parameters: `refc` \- the class or interface from which the method is accessed `type` \- the type of the method, with the receiver argument omitted, and a void return type Returns: the desired method handle Throws: `[NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang")` \- if the constructor does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### findClass public [Class](../../../java/lang/Class.html "class in java.lang")<?> findClass([String](../../../java/lang/String.html "class in java.lang") targetName) throws [ClassNotFoundException](../../../java/lang/ClassNotFoundException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Looks up a class by name from the lookup context defined by this `Lookup` object. The static initializer of the class is not run. The lookup context here is determined by the [lookup class](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupClass--), its class loader, and the [lookup modes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). In particular, the method first attempts to load the requested class, and then determines whether the class is accessible to this lookup object. Parameters: `targetName` \- the fully qualified name of the class to be looked up. Returns: the requested class. Throws: `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[LinkageError](../../../java/lang/LinkageError.html "class in java.lang")` \- if the linkage fails `[ClassNotFoundException](../../../java/lang/ClassNotFoundException.html "class in java.lang")` \- if the class cannot be loaded by the lookup class' loader. `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if the class is not accessible, using the allowed access modes. `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) Since: 9 * #### accessClass public [Class](../../../java/lang/Class.html "class in java.lang")<?> accessClass([Class](../../../java/lang/Class.html "class in java.lang")<?> targetClass) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Determines if a class can be accessed from the lookup context defined by this `Lookup` object. The static initializer of the class is not run. The lookup context here is determined by the [lookup class](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupClass--) and the[lookup modes](../../../java/lang/invoke/MethodHandles.Lookup.html#lookupModes--). Parameters: `targetClass` \- the class to be access-checked Returns: the class that has been access-checked Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if the class is not accessible from the lookup class, using the allowed access modes. `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) Since: 9 * #### findSpecial public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findSpecial([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [MethodType](../../../java/lang/invoke/MethodType.html "class in java.lang.invoke") type, [Class](../../../java/lang/Class.html "class in java.lang")<?> specialCaller) throws [NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces an early-bound method handle for a virtual method. It will bypass checks for overriding methods on the receiver,[as if called](MethodHandles.Lookup.html#equiv) from an `invokespecial` instruction from within the explicitly specified `specialCaller`. The type of the method handle will be that of the method, with a suitably restricted receiver type prepended. (The receiver type will be `specialCaller` or a subtype.) The method and all its argument types must be accessible to the lookup object. Before method resolution, if the explicitly specified caller class is not identical with the lookup class, or if this lookup object does not have[private access](MethodHandles.Lookup.html#privacc) privileges, the access fails. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the method's variable arity modifier bit (`0x0080`) is set. _(Note: JVM internal methods named `"<init>"` are not visible to this API, even though the `invokespecial` instruction can refer to them in special circumstances. Use [findConstructor](../../../java/lang/invoke/MethodHandles.Lookup.html#findConstructor-java.lang.Class-java.lang.invoke.MethodType-) to access instance initialization methods in a safe manner.)_ **Example:** > ``` > > 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 > > ``` Parameters: `refc` \- the class or interface from which the method is accessed `name` \- the name of the method (which must not be "<init>") `type` \- the type of the method, with the receiver argument omitted `specialCaller` \- the proposed calling class to perform the `invokespecial` Returns: the desired method handle Throws: `[NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang")` \- if the method does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the method is `static`, or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### findGetter public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findGetter([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [Class](../../../java/lang/Class.html "class in java.lang")<?> type) throws [NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle giving read access to a non-static field. The type of the method handle will have a return type of the field's value type. The method handle's single argument will be the instance containing the field. Access checking is performed immediately on behalf of the lookup class. Parameters: `refc` \- the class or interface from which the method is accessed `name` \- the field's name `type` \- the field's type Returns: a method handle which can load values from the field Throws: `[NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang")` \- if the field does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the field is `static` `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null See Also: [findVarHandle(Class, String, Class)](../../../java/lang/invoke/MethodHandles.Lookup.html#findVarHandle-java.lang.Class-java.lang.String-java.lang.Class-) * #### findSetter public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findSetter([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [Class](../../../java/lang/Class.html "class in java.lang")<?> type) throws [NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle giving write access to a non-static field. The type of the method handle will have a void return type. The method handle will take two arguments, the instance containing the field, and the value to be stored. The second argument will be of the field's value type. Access checking is performed immediately on behalf of the lookup class. Parameters: `refc` \- the class or interface from which the method is accessed `name` \- the field's name `type` \- the field's type Returns: a method handle which can store values into the field Throws: `[NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang")` \- if the field does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the field is `static` `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null See Also: [findVarHandle(Class, String, Class)](../../../java/lang/invoke/MethodHandles.Lookup.html#findVarHandle-java.lang.Class-java.lang.String-java.lang.Class-) * #### findVarHandle public [VarHandle](../../../java/lang/invoke/VarHandle.html "class in java.lang.invoke") findVarHandle([Class](../../../java/lang/Class.html "class in java.lang")<?> recv, [String](../../../java/lang/String.html "class in java.lang") name, [Class](../../../java/lang/Class.html "class in java.lang")<?> type) throws [NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a VarHandle giving access to a non-static field `name` of type `type` declared in a class of type `recv`. The VarHandle's variable type is `type` and it has one coordinate type, `recv`. Access checking is performed immediately on behalf of the lookup class. Certain access modes of the returned VarHandle are unsupported under the following conditions: * if the field is declared `final`, then the write, atomic update, numeric atomic update, and bitwise atomic update access modes are unsupported. * if the field type is anything other than `byte`,`short`, `char`, `int`, `long`,`float`, or `double` then numeric atomic update access modes are unsupported. * if the field type is anything other than `boolean`,`byte`, `short`, `char`, `int` or`long` then bitwise atomic update access modes are unsupported. If the field is declared `volatile` then the returned VarHandle will override access to the field (effectively ignore the`volatile` declaration) in accordance to its specified access modes. If the field type is `float` or `double` then numeric and atomic update access modes compare values using their bitwise representation (see [Float.floatToRawIntBits(float)](../../../java/lang/Float.html#floatToRawIntBits-float-) and[Double.doubleToRawLongBits(double)](../../../java/lang/Double.html#doubleToRawLongBits-double-), respectively). API Note: Bitwise comparison of `float` values or `double` values, as performed by the numeric and atomic update access modes, differ from the primitive `==` operator and the [Float.equals(java.lang.Object)](../../../java/lang/Float.html#equals-java.lang.Object-) and [Double.equals(java.lang.Object)](../../../java/lang/Double.html#equals-java.lang.Object-) methods, specifically with respect to comparing NaN values or comparing `-0.0` with `+0.0`. Care should be taken when performing a compare and set or a compare and exchange operation with such values since the operation may unexpectedly fail. There are many possible NaN values that are considered to be`NaN` in Java, although no IEEE 754 floating-point operation provided by Java can distinguish between them. Operation failure can occur if the expected or witness value is a NaN value and it is transformed (perhaps in a platform specific manner) into another NaN value, and thus has a different bitwise representation (see[Float.intBitsToFloat(int)](../../../java/lang/Float.html#intBitsToFloat-int-) or [Double.longBitsToDouble(long)](../../../java/lang/Double.html#longBitsToDouble-long-) for more details). The values `-0.0` and `+0.0` have different bitwise representations but are considered equal when using the primitive`==` operator. Operation failure can occur if, for example, a numeric algorithm computes an expected value to be say `-0.0` and previously computed the witness value to be say `+0.0`. Parameters: `recv` \- the receiver class, of type `R`, that declares the non-static field `name` \- the field's name `type` \- the field's type, of type `T` Returns: a VarHandle giving access to non-static fields. Throws: `[NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang")` \- if the field does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the field is `static` `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null Since: 9 * #### findStaticGetter public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findStaticGetter([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [Class](../../../java/lang/Class.html "class in java.lang")<?> type) throws [NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle giving read access to a static field. The type of the method handle will have a return type of the field's value type. The method handle will take no arguments. Access checking is performed immediately on behalf of the lookup class. If the returned method handle is invoked, the field's class will be initialized, if it has not already been initialized. Parameters: `refc` \- the class or interface from which the method is accessed `name` \- the field's name `type` \- the field's type Returns: a method handle which can load values from the field Throws: `[NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang")` \- if the field does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the field is not `static` `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### findStaticSetter public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") findStaticSetter([Class](../../../java/lang/Class.html "class in java.lang")<?> refc, [String](../../../java/lang/String.html "class in java.lang") name, [Class](../../../java/lang/Class.html "class in java.lang")<?> type) throws [NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle giving write access to a static field. The type of the method handle will have a void return type. The method handle will take a single argument, of the field's value type, the value to be stored. Access checking is performed immediately on behalf of the lookup class. If the returned method handle is invoked, the field's class will be initialized, if it has not already been initialized. Parameters: `refc` \- the class or interface from which the method is accessed `name` \- the field's name `type` \- the field's type Returns: a method handle which can store values into the field Throws: `[NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang")` \- if the field does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the field is not `static` `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### findStaticVarHandle public [VarHandle](../../../java/lang/invoke/VarHandle.html "class in java.lang.invoke") findStaticVarHandle([Class](../../../java/lang/Class.html "class in java.lang")<?> decl, [String](../../../java/lang/String.html "class in java.lang") name, [Class](../../../java/lang/Class.html "class in java.lang")<?> type) throws [NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a VarHandle giving access to a static field `name` of type `type` declared in a class of type `decl`. The VarHandle's variable type is `type` and it has no coordinate types. Access checking is performed immediately on behalf of the lookup class. If the returned VarHandle is operated on, the declaring class will be initialized, if it has not already been initialized. Certain access modes of the returned VarHandle are unsupported under the following conditions: * if the field is declared `final`, then the write, atomic update, numeric atomic update, and bitwise atomic update access modes are unsupported. * if the field type is anything other than `byte`,`short`, `char`, `int`, `long`,`float`, or `double`, then numeric atomic update access modes are unsupported. * if the field type is anything other than `boolean`,`byte`, `short`, `char`, `int` or`long` then bitwise atomic update access modes are unsupported. If the field is declared `volatile` then the returned VarHandle will override access to the field (effectively ignore the`volatile` declaration) in accordance to its specified access modes. If the field type is `float` or `double` then numeric and atomic update access modes compare values using their bitwise representation (see [Float.floatToRawIntBits(float)](../../../java/lang/Float.html#floatToRawIntBits-float-) and[Double.doubleToRawLongBits(double)](../../../java/lang/Double.html#doubleToRawLongBits-double-), respectively). API Note: Bitwise comparison of `float` values or `double` values, as performed by the numeric and atomic update access modes, differ from the primitive `==` operator and the [Float.equals(java.lang.Object)](../../../java/lang/Float.html#equals-java.lang.Object-) and [Double.equals(java.lang.Object)](../../../java/lang/Double.html#equals-java.lang.Object-) methods, specifically with respect to comparing NaN values or comparing `-0.0` with `+0.0`. Care should be taken when performing a compare and set or a compare and exchange operation with such values since the operation may unexpectedly fail. There are many possible NaN values that are considered to be`NaN` in Java, although no IEEE 754 floating-point operation provided by Java can distinguish between them. Operation failure can occur if the expected or witness value is a NaN value and it is transformed (perhaps in a platform specific manner) into another NaN value, and thus has a different bitwise representation (see[Float.intBitsToFloat(int)](../../../java/lang/Float.html#intBitsToFloat-int-) or [Double.longBitsToDouble(long)](../../../java/lang/Double.html#longBitsToDouble-long-) for more details). The values `-0.0` and `+0.0` have different bitwise representations but are considered equal when using the primitive`==` operator. Operation failure can occur if, for example, a numeric algorithm computes an expected value to be say `-0.0` and previously computed the witness value to be say `+0.0`. Parameters: `decl` \- the class that declares the static field `name` \- the field's name `type` \- the field's type, of type `T` Returns: a VarHandle giving access to a static field Throws: `[NoSuchFieldException](../../../java/lang/NoSuchFieldException.html "class in java.lang")` \- if the field does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the field is not `static` `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null Since: 9 * #### bind public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") bind([Object](../../../java/lang/Object.html "class in java.lang") receiver, [String](../../../java/lang/String.html "class in java.lang") name, [MethodType](../../../java/lang/invoke/MethodType.html "class in java.lang.invoke") type) throws [NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang"), [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces an early-bound method handle for a non-static method. The receiver must have a supertype `defc` in which a method of the given name and type is accessible to the lookup class. The method and all its argument types must be accessible to the lookup object. The type of the method handle will be that of the method, without any insertion of an additional receiver parameter. The given receiver will be bound into the method handle, so that every call to the method handle will invoke the requested method on the given receiver. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the method's variable arity modifier bit (`0x0080`) is set_and_ the trailing array argument is not the only argument. (If the trailing array argument is the only argument, the given receiver value will be bound to it.) This is almost equivalent to the following code, with some differences noted below: > ``` > > 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; > > ``` where `defc` is either `receiver.getClass()` or a super type of that class, in which the requested method is accessible to the lookup class. (Unlike `bind`, `bindTo` does not preserve variable arity. Also, `bindTo` may throw a `ClassCastException` in instances where `bind` would throw an `IllegalAccessException`, as in the case where the member is `protected` and the receiver is restricted by `findVirtual` to the lookup class.) Parameters: `receiver` \- the object from which the method is accessed `name` \- the name of the method `type` \- the type of the method, with the receiver argument omitted Returns: the desired method handle Throws: `[NoSuchMethodException](../../../java/lang/NoSuchMethodException.html "class in java.lang")` \- if the method does not exist `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null See Also: [MethodHandle.bindTo(java.lang.Object)](../../../java/lang/invoke/MethodHandle.html#bindTo-java.lang.Object-), [findVirtual(java.lang.Class<?>, java.lang.String, java.lang.invoke.MethodType)](../../../java/lang/invoke/MethodHandles.Lookup.html#findVirtual-java.lang.Class-java.lang.String-java.lang.invoke.MethodType-) * #### unreflect public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") unreflect([Method](../../../java/lang/reflect/Method.html "class in java.lang.reflect") m) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Makes a [direct method handle](MethodHandleInfo.html#directmh) to _m_, if the lookup class has permission. If _m_ is non-static, the receiver argument is treated as an initial argument. If _m_ is virtual, overriding is respected on every call. Unlike the Core Reflection API, exceptions are _not_ wrapped. The type of the method handle will be that of the method, with the receiver type prepended (but only if it is non-static). If the method's `accessible` flag is not set, access checking is performed immediately on behalf of the lookup class. If _m_ is not public, do not share the resulting handle with untrusted parties. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the method's variable arity modifier bit (`0x0080`) is set. If _m_ is static, and if the returned method handle is invoked, the method's class will be initialized, if it has not already been initialized. Parameters: `m` \- the reflected method Returns: a method handle which can invoke the reflected method Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the argument is null * #### unreflectSpecial public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") unreflectSpecial([Method](../../../java/lang/reflect/Method.html "class in java.lang.reflect") m, [Class](../../../java/lang/Class.html "class in java.lang")<?> specialCaller) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle for a reflected method. It will bypass checks for overriding methods on the receiver,[as if called](MethodHandles.Lookup.html#equiv) from an `invokespecial` instruction from within the explicitly specified `specialCaller`. The type of the method handle will be that of the method, with a suitably restricted receiver type prepended. (The receiver type will be `specialCaller` or a subtype.) If the method's `accessible` flag is not set, access checking is performed immediately on behalf of the lookup class, as if `invokespecial` instruction were being linked. Before method resolution, if the explicitly specified caller class is not identical with the lookup class, or if this lookup object does not have[private access](MethodHandles.Lookup.html#privacc) privileges, the access fails. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the method's variable arity modifier bit (`0x0080`) is set. Parameters: `m` \- the reflected method `specialCaller` \- the class nominally calling the method Returns: a method handle which can invoke the reflected method Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails, or if the method is `static`, or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if any argument is null * #### unreflectConstructor public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") unreflectConstructor([Constructor](../../../java/lang/reflect/Constructor.html "class in java.lang.reflect")<?> c) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle for a reflected constructor. The type of the method handle will be that of the constructor, with the return type changed to the declaring class. The method handle will perform a `newInstance` operation, creating a new instance of the constructor's class on the arguments passed to the method handle. If the constructor's `accessible` flag is not set, access checking is performed immediately on behalf of the lookup class. The returned method handle will have[variable arity](../../../java/lang/invoke/MethodHandle.html#asVarargsCollector-java.lang.Class-) if and only if the constructor's variable arity modifier bit (`0x0080`) is set. If the returned method handle is invoked, the constructor's class will be initialized, if it has not already been initialized. Parameters: `c` \- the reflected constructor Returns: a method handle which can invoke the reflected constructor Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails or if the method's variable arity modifier bit is set and `asVarargsCollector` fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the argument is null * #### unreflectGetter public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") unreflectGetter([Field](../../../java/lang/reflect/Field.html "class in java.lang.reflect") f) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle giving read access to a reflected field. The type of the method handle will have a return type of the field's value type. If the field is static, the method handle will take no arguments. Otherwise, its single argument will be the instance containing the field. If the field's `accessible` flag is not set, access checking is performed immediately on behalf of the lookup class. If the field is static, and if the returned method handle is invoked, the field's class will be initialized, if it has not already been initialized. Parameters: `f` \- the reflected field Returns: a method handle which can load values from the reflected field Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the argument is null * #### unreflectSetter public [MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") unreflectSetter([Field](../../../java/lang/reflect/Field.html "class in java.lang.reflect") f) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a method handle giving write access to a reflected field. The type of the method handle will have a void return type. If the field is static, the method handle will take a single argument, of the field's value type, the value to be stored. Otherwise, the two arguments will be the instance containing the field, and the value to be stored. If the field's `accessible` flag is not set, access checking is performed immediately on behalf of the lookup class. If the field is static, and if the returned method handle is invoked, the field's class will be initialized, if it has not already been initialized. Parameters: `f` \- the reflected field Returns: a method handle which can store values into the reflected field Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the argument is null * #### unreflectVarHandle public [VarHandle](../../../java/lang/invoke/VarHandle.html "class in java.lang.invoke") unreflectVarHandle([Field](../../../java/lang/reflect/Field.html "class in java.lang.reflect") f) throws [IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang") Produces a VarHandle giving access to a reflected field `f` of type `T` declared in a class of type `R`. The VarHandle's variable type is `T`. If the field is non-static the VarHandle has one coordinate type,`R`. Otherwise, the field is static, and the VarHandle has no coordinate types. Access checking is performed immediately on behalf of the lookup class, regardless of the value of the field's `accessible` flag. If the field is static, and if the returned VarHandle is operated on, the field's declaring class will be initialized, if it has not already been initialized. Certain access modes of the returned VarHandle are unsupported under the following conditions: * if the field is declared `final`, then the write, atomic update, numeric atomic update, and bitwise atomic update access modes are unsupported. * if the field type is anything other than `byte`,`short`, `char`, `int`, `long`,`float`, or `double` then numeric atomic update access modes are unsupported. * if the field type is anything other than `boolean`,`byte`, `short`, `char`, `int` or`long` then bitwise atomic update access modes are unsupported. If the field is declared `volatile` then the returned VarHandle will override access to the field (effectively ignore the`volatile` declaration) in accordance to its specified access modes. If the field type is `float` or `double` then numeric and atomic update access modes compare values using their bitwise representation (see [Float.floatToRawIntBits(float)](../../../java/lang/Float.html#floatToRawIntBits-float-) and[Double.doubleToRawLongBits(double)](../../../java/lang/Double.html#doubleToRawLongBits-double-), respectively). API Note: Bitwise comparison of `float` values or `double` values, as performed by the numeric and atomic update access modes, differ from the primitive `==` operator and the [Float.equals(java.lang.Object)](../../../java/lang/Float.html#equals-java.lang.Object-) and [Double.equals(java.lang.Object)](../../../java/lang/Double.html#equals-java.lang.Object-) methods, specifically with respect to comparing NaN values or comparing `-0.0` with `+0.0`. Care should be taken when performing a compare and set or a compare and exchange operation with such values since the operation may unexpectedly fail. There are many possible NaN values that are considered to be`NaN` in Java, although no IEEE 754 floating-point operation provided by Java can distinguish between them. Operation failure can occur if the expected or witness value is a NaN value and it is transformed (perhaps in a platform specific manner) into another NaN value, and thus has a different bitwise representation (see[Float.intBitsToFloat(int)](../../../java/lang/Float.html#intBitsToFloat-int-) or [Double.longBitsToDouble(long)](../../../java/lang/Double.html#longBitsToDouble-long-) for more details). The values `-0.0` and `+0.0` have different bitwise representations but are considered equal when using the primitive`==` operator. Operation failure can occur if, for example, a numeric algorithm computes an expected value to be say `-0.0` and previously computed the witness value to be say `+0.0`. Parameters: `f` \- the reflected field, with a field of type `T`, and a declaring class of type `R` Returns: a VarHandle giving access to non-static fields or a static field Throws: `[IllegalAccessException](../../../java/lang/IllegalAccessException.html "class in java.lang")` \- if access checking fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the argument is null Since: 9 * #### revealDirect public [MethodHandleInfo](../../../java/lang/invoke/MethodHandleInfo.html "interface in java.lang.invoke") revealDirect([MethodHandle](../../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke") target) Cracks a [direct method handle](MethodHandleInfo.html#directmh) created by this lookup object or a similar one. Security and access checks are performed to ensure that this lookup object is capable of reproducing the target method handle. This means that the cracking may fail if target is a direct method handle but was created by an unrelated lookup object. This can happen if the method handle is [caller sensitive](MethodHandles.Lookup.html#callsens) and was created by a lookup object for a different class. Parameters: `target` \- a direct method handle to crack into symbolic reference components Returns: a symbolic reference which can be used to reconstruct this method handle from this lookup object Throws: `[SecurityException](../../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager is present and it[refuses access](MethodHandles.Lookup.html#secmgr) `[IllegalArgumentException](../../../java/lang/IllegalArgumentException.html "class in java.lang")` \- if the target is not a direct method handle or if access checking fails `[NullPointerException](../../../java/lang/NullPointerException.html "class in java.lang")` \- if the target is `null` Since: 1.8 See Also: [MethodHandleInfo](../../../java/lang/invoke/MethodHandleInfo.html "interface in java.lang.invoke") * #### hasPrivateAccess public boolean hasPrivateAccess() Returns `true` if this lookup has `PRIVATE` access. Returns: `true` if this lookup has `PRIVATE` access. Since: 9