- java.lang.Object
-
- java.lang.invoke.MethodHandles.Lookup
-
- 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 call
MethodHandles.lookup
to create a factory for itself. When theLookup
factory object is created, the identity of the lookup class is determined, and securely stored in theLookup
object. The lookup class (or its delegates) may then use factory methods on theLookup
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.The factory methods on a
Lookup
object correspond to all major use cases for methods, constructors, and fields. Here is a summary of the correspondence between these factory methods and the behavior the resulting method handles: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
is the class or interface being searched for a member, documented as a parameter namedrefc
in the lookup methods. The method or constructor typeMT
is composed from the return typeT
and the sequence of argument typesA*
. BothMT
and the field typeFT
are documented as a parameter namedtype
. The formal parameterthis
stands for the self-reference of typeC
; if it is present, it is always the leading argument to the method handle invocation. (In the case of someprotected
members,this
may be restricted in type to the lookup class; see below.) The namearg
stands for all the other method handle arguments. In the code examples for the Core Reflection API, the namethisOrNull
stands for a null reference if the accessed method or field is static, andthis
otherwise. The namesaMethod
,aField
, andaConstructor
stand for reflective objects corresponding to the given members.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.
The equivalence between looked-up method handles and underlying class members 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 is not subject to security manager checks.
Access checking
Access checks are applied in the factory methods ofLookup
, 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 singleLookup
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 sharedLookup
object delegates the capability to create method handles on private members of the lookup class. Even if privileged code uses theLookup
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. 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 method
M
are exactly equivalent to the conditions under which the lookup class could have compiled 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 and resolved call toM
. The same point is true of fields and constructors.If the desired member is
protected
, 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 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 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 class
C.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 theLookup.in
method, which can transform a lookup onC.E
into one on any of those other classes, without special elevation of privilege.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 asinvokestatic
orgetfield
. There is a security manager API to allow applications to check such cross-loader references. These checks apply to both theMethodHandles.Lookup
API and the Core Reflection API (as found onClass
).Access checks only apply to named and reflected methods, constructors, and fields. Other method handle creation methods, such as
MethodHandle.asType
, do not require any access checks, and are done with static methods ofMethodHandles
, independently of anyLookup
object.Security manager interactions
If a security manager is present, member lookups are subject to additional checks. From one to four calls are made to the security manager. Any of these calls can refuse access by throwing aSecurityException
. Definesmgr
as the security manager,refc
as the containing class in which the member is being sought, anddefc
as the class in which the member is actually defined. The calls are made according to the following rules:- In all cases,
smgr.checkMemberAccess(refc, Member.PUBLIC)
is called. - If the class loader of the lookup class is not
the same as or an ancestor of the class loader of
refc
, thensmgr.checkPackageAccess(refcPkg)
is called, whererefcPkg
is the package ofrefc
. - If the retrieved member is not public,
smgr.checkMemberAccess(defc, Member.DECLARED)
is called. (Note thatdefc
might be the same asrefc
.) The default implementation of this security manager method inspects the stack to determine the original caller of the reflective request (such asfindStatic
), and performs additional permission checks if the class loader ofdefc
differs from the class loader of the class from which the reflective request came. - If the retrieved member is not public,
and if
defc
andrefc
are in different class loaders, and if the class loader of the lookup class is not the same as or an ancestor of the class loader ofdefc
, thensmgr.checkPackageAccess(defcPkg)
is called, wheredefcPkg
is the package ofdefc
.
-
-
Field Summary
Fields Modifier and Type Field and Description static int
PACKAGE
A single-bit mask representingpackage
access (default access), which may contribute to the result oflookupModes
.static int
PRIVATE
A single-bit mask representingprivate
access, which may contribute to the result oflookupModes
.static int
PROTECTED
A single-bit mask representingprotected
access, which may contribute to the result oflookupModes
.static int
PUBLIC
A single-bit mask representingpublic
access, which may contribute to the result oflookupModes
.
-
Method Summary
Methods Modifier and Type Method and Description MethodHandle
bind(Object receiver, String name, MethodType type)
Produces an early-bound method handle for a non-static method.MethodHandle
findConstructor(Class<?> refc, MethodType type)
Produces a method handle which creates an object and initializes it, using the constructor of the specified type.MethodHandle
findGetter(Class<?> refc, String name, Class<?> type)
Produces a method handle giving read access to a non-static field.MethodHandle
findSetter(Class<?> refc, String name, Class<?> type)
Produces a method handle giving write access to a non-static field.MethodHandle
findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller)
Produces an early-bound method handle for a virtual method, as if called from aninvokespecial
instruction fromcaller
.MethodHandle
findStatic(Class<?> refc, String name, MethodType type)
Produces a method handle for a static method.MethodHandle
findStaticGetter(Class<?> refc, String name, Class<?> type)
Produces a method handle giving read access to a static field.MethodHandle
findStaticSetter(Class<?> refc, String name, Class<?> type)
Produces a method handle giving write access to a static field.MethodHandle
findVirtual(Class<?> refc, String name, MethodType type)
Produces a method handle for a virtual method.MethodHandles.Lookup
in(Class<?> requestedLookupClass)
Creates a lookup on the specified new lookup class.Class<?>
lookupClass()
Tells which class is performing the lookup.int
lookupModes()
Tells which access-protection classes of members this lookup object can produce.String
toString()
Displays the name of the class from which lookups are to be made.MethodHandle
unreflect(Method m)
Makes a direct method handle to m, if the lookup class has permission.MethodHandle
unreflectConstructor(Constructor c)
Produces a method handle for a reflected constructor.MethodHandle
unreflectGetter(Field f)
Produces a method handle giving read access to a reflected field.MethodHandle
unreflectSetter(Field f)
Produces a method handle giving write access to a reflected field.MethodHandle
unreflectSpecial(Method m, Class<?> specialCaller)
Produces a method handle for a reflected method.
-
-
-
Field Detail
-
PUBLIC
public static final int PUBLIC
A single-bit mask representingpublic
access, which may contribute to the result oflookupModes
. The value,0x01
, happens to be the same as the value of thepublic
modifier bit.- See Also:
- Constant Field Values
-
PRIVATE
public static final int PRIVATE
A single-bit mask representingprivate
access, which may contribute to the result oflookupModes
. The value,0x02
, happens to be the same as the value of theprivate
modifier bit.- See Also:
- Constant Field Values
-
PROTECTED
public static final int PROTECTED
A single-bit mask representingprotected
access, which may contribute to the result oflookupModes
. The value,0x04
, happens to be the same as the value of theprotected
modifier bit.- See Also:
- Constant Field Values
-
PACKAGE
public static final int PACKAGE
A single-bit mask representingpackage
access (default access), which may contribute to the result oflookupModes
. The value is0x08
, which does not correspond meaningfully to any particular modifier bit.- See Also:
- Constant Field Values
-
-
Method Detail
-
lookupClass
public Class<?> 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
, which controls whether non-public members can be accessed.
-
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), PRIVATE (0x02), PROTECTED (0x04), and PACKAGE (0x08).A freshly-created lookup object on the caller's class has all possible bits set, since the caller class can access all its own members. A lookup object on a new lookup class created from a previous lookup object may have some mode bits set to zero. 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.
-
in
public MethodHandles.Lookup in(Class<?> requestedLookupClass)
Creates a lookup on the specified new lookup class. The resulting object will report the specified class as its ownlookupClass
.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 new lookup class differs from the old one, 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 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.
- 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.)
- Parameters:
requestedLookupClass
- the desired lookup class for the new lookup object- Returns:
- a lookup object which reports the desired lookup class
- Throws:
NullPointerException
- if the argument is null
-
toString
public String toString()
Displays the name of the class from which lookups are to be made. (The name is the one reported byClass.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 is allowed, the suffix is "/public".
- If only public and package access are allowed, the suffix is "/package".
- If only public, package, and private access are allowed, the suffix is "/private".
MethodHandles.lookup
. Objects created byLookup.in
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
in classObject
- Returns:
- a string representation of the object.
- See Also:
in(java.lang.Class<?>)
-
findStatic
public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
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 withfindVirtual
orfindSpecial
.) The method and all its argument types must be accessible to the lookup class. If the method's class has not yet been initialized, that is done immediately, before the method handle is returned.The returned method handle will have variable arity if and only if the method's variable arity modifier bit (
0x0080
) is set. 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 accessedname
- the name of the methodtype
- the type of the method- Returns:
- the desired method handle
- Throws:
NoSuchMethodException
- if the method does not existIllegalAccessException
- if access checking fails, or if the method is notstatic
, or if the method's variable arity modifier bit is set andasVarargsCollector
failsSecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findVirtual
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
Produces a method handle for a virtual method. The type of the method handle will be that of the method, with the receiver type (usuallyrefc
) prepended. The method and all its argument types must be accessible to the lookup class.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
orinvokeinterface
instruction.)The first argument will be of type
refc
if the lookup class has full privileges to access the member. Otherwise the member must beprotected
and the first argument will be restricted in type to the lookup class.The returned method handle will have variable arity if and only if the method's variable arity modifier bit (
0x0080
) is set.Because of the general equivalence between
invokevirtual
instructions and method handles produced byfindVirtual
, if the class isMethodHandle
and the name string isinvokeExact
orinvoke
, the resulting method handle is equivalent to one produced byMethodHandles.exactInvoker
orMethodHandles.invoker
with the sametype
argument. 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 accessedname
- the name of the methodtype
- the type of the method, with the receiver argument omitted- Returns:
- the desired method handle
- Throws:
NoSuchMethodException
- if the method does not existIllegalAccessException
- if access checking fails, or if the method isstatic
or if the method's variable arity modifier bit is set andasVarargsCollector
failsSecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findConstructor
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException
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 class. If the constructor's class has not yet been initialized, that is done immediately, before the method handle is returned.(Note: 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 if and only if the constructor's variable arity modifier bit (
0x0080
) is set. 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 accessedtype
- the type of the method, with the receiver argument omitted, and a void return type- Returns:
- the desired method handle
- Throws:
NoSuchMethodException
- if the constructor does not existIllegalAccessException
- if access checking fails or if the method's variable arity modifier bit is set andasVarargsCollector
failsSecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findSpecial
public MethodHandle findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException
Produces an early-bound method handle for a virtual method, as if called from aninvokespecial
instruction fromcaller
. The type of the method handle will be that of the method, with a suitably restricted receiver type (such ascaller
) prepended. The method and all its argument types must be accessible to the caller.When called, the handle will treat the first argument as a receiver, but will not dispatch on the receiver's type. (This direct invocation action is identical with that performed by an
invokespecial
instruction.)If the explicitly specified caller class is not identical with the lookup class, or if this lookup object does not have private access privileges, the access fails.
The returned method handle will have variable arity if and only if the method's variable arity modifier bit (
0x0080
) is set.(Note: JVM internal methods named
<init>
not visible to this API, even though theinvokespecial
instruction can refer to them in special circumstances. UsefindConstructor
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 accessedname
- the name of the method (which must not be "<init>")type
- the type of the method, with the receiver argument omittedspecialCaller
- the proposed calling class to perform theinvokespecial
- Returns:
- the desired method handle
- Throws:
NoSuchMethodException
- if the method does not existIllegalAccessException
- if access checking fails or if the method's variable arity modifier bit is set andasVarargsCollector
failsSecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findGetter
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
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 accessedname
- the field's nametype
- the field's type- Returns:
- a method handle which can load values from the field
- Throws:
NoSuchFieldException
- if the field does not existIllegalAccessException
- if access checking fails, or if the field isstatic
SecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findSetter
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
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 accessedname
- the field's nametype
- the field's type- Returns:
- a method handle which can store values into the field
- Throws:
NoSuchFieldException
- if the field does not existIllegalAccessException
- if access checking fails, or if the field isstatic
SecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findStaticGetter
public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
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.- Parameters:
refc
- the class or interface from which the method is accessedname
- the field's nametype
- the field's type- Returns:
- a method handle which can load values from the field
- Throws:
NoSuchFieldException
- if the field does not existIllegalAccessException
- if access checking fails, or if the field is notstatic
SecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
findStaticSetter
public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
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.- Parameters:
refc
- the class or interface from which the method is accessedname
- the field's nametype
- the field's type- Returns:
- a method handle which can store values into the field
- Throws:
NoSuchFieldException
- if the field does not existIllegalAccessException
- if access checking fails, or if the field is notstatic
SecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
bind
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
Produces an early-bound method handle for a non-static method. The receiver must have a supertypedefc
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 class. 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 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 equivalent to the following code:
whereimport 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
is eitherreceiver.getClass()
or a super type of that class, in which the requested method is accessible to the lookup class. (Note thatbindTo
does not preserve variable arity.)- Parameters:
receiver
- the object from which the method is accessedname
- the name of the methodtype
- the type of the method, with the receiver argument omitted- Returns:
- the desired method handle
- Throws:
NoSuchMethodException
- if the method does not existIllegalAccessException
- if access checking fails or if the method's variable arity modifier bit is set andasVarargsCollector
failsSecurityException
- if a security manager is present and it refuses accessNullPointerException
- if any argument is null
-
unreflect
public MethodHandle unreflect(Method m) throws IllegalAccessException
Makes a direct method handle 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'saccessible
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 if and only if the method's variable arity modifier bit (
0x0080
) is set.- Parameters:
m
- the reflected method- Returns:
- a method handle which can invoke the reflected method
- Throws:
IllegalAccessException
- if access checking fails or if the method's variable arity modifier bit is set andasVarargsCollector
failsNullPointerException
- if the argument is null
-
unreflectSpecial
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException
Produces a method handle for a reflected method. It will bypass checks for overriding methods on the receiver, as if by ainvokespecial
instruction from within thespecialCaller
. The type of the method handle will be that of the method, with the special caller type prepended (and not the receiver of the method). If the method'saccessible
flag is not set, access checking is performed immediately on behalf of the lookup class, as ifinvokespecial
instruction were being linked.The returned method handle will have variable arity if and only if the method's variable arity modifier bit (
0x0080
) is set.- Parameters:
m
- the reflected methodspecialCaller
- the class nominally calling the method- Returns:
- a method handle which can invoke the reflected method
- Throws:
IllegalAccessException
- if access checking fails or if the method's variable arity modifier bit is set andasVarargsCollector
failsNullPointerException
- if any argument is null
-
unreflectConstructor
public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException
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 anewInstance
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 if and only if the constructor's variable arity modifier bit (
0x0080
) is set.- Parameters:
c
- the reflected constructor- Returns:
- a method handle which can invoke the reflected constructor
- Throws:
IllegalAccessException
- if access checking fails or if the method's variable arity modifier bit is set andasVarargsCollector
failsNullPointerException
- if the argument is null
-
unreflectGetter
public MethodHandle unreflectGetter(Field f) throws IllegalAccessException
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'saccessible
flag is not set, access checking is performed immediately on behalf of the lookup class.- Parameters:
f
- the reflected field- Returns:
- a method handle which can load values from the reflected field
- Throws:
IllegalAccessException
- if access checking failsNullPointerException
- if the argument is null
-
unreflectSetter
public MethodHandle unreflectSetter(Field f) throws IllegalAccessException
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'saccessible
flag is not set, access checking is performed immediately on behalf of the lookup class.- Parameters:
f
- the reflected field- Returns:
- a method handle which can store values into the reflected field
- Throws:
IllegalAccessException
- if access checking failsNullPointerException
- if the argument is null
-
-
Document created the 11/06/2005, last modified the 04/03/2020
Source of the printed document:https://www.gaudry.be/en/java-api-rf-java/lang/invoke/MethodHandles.Lookup.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.
References
These references and links indicate documents consulted during the writing of this page, or which may provide additional information, but the authors of these sources can not be held responsible for the content of this page.
The author This site is solely responsible for the way in which the various concepts, and the freedoms that are taken with the reference works, are presented here. Remember that you must cross multiple source information to reduce the risk of errors.