|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.dyn.MethodHandles
public class MethodHandles
Disabled: no SafeJ information.
Fundamental operations and utilities for MethodHandle. They fall into several categories:
Nested Class Summary | |
---|---|
static class |
MethodHandles.Lookup
A factory object for creating method handles, when the creation requires access checking. |
Method Summary | |
---|---|
static MethodHandle |
arrayElementGetter(Class<?> arrayClass)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle giving read access to elements of an array. |
static MethodHandle |
arrayElementSetter(Class<?> arrayClass)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle giving write access to elements of an array. |
static MethodHandle |
catchException(MethodHandle target,
Class<? extends Throwable> exType,
MethodHandle handler)
PROVISIONAL API, WORK IN PROGRESS: Make a method handle which adapts a target method handle, by running it inside an exception handler. |
static MethodHandle |
collectArguments(MethodHandle target,
MethodType newType)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which adapts the type of the given method handle to a new type, by collecting a series of trailing arguments as elements to a single argument array. |
static MethodHandle |
convertArguments(MethodHandle target,
MethodType newType)
Produce a method handle which adapts the type of the given method handle to a new type by pairwise argument conversion. |
static MethodHandle |
dropArguments(MethodHandle target,
int pos,
Class<?>... valueTypes)
|
static MethodHandle |
dropArguments(MethodHandle target,
int pos,
List<Class<?>> valueTypes)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which calls the original method handle, after dropping the given argument(s) at the given position. |
static MethodHandle |
dynamicInvoker(CallSite site)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle equivalent to an invokedynamic instruction which has been linked to the given call site. |
static MethodHandle |
exactInvoker(MethodType type)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which will take a invoke any method handle of the given type. |
static MethodHandle |
filterArguments(MethodHandle target,
MethodHandle... filters)
PROVISIONAL API, WORK IN PROGRESS: Adapt a target method handle target by pre-processing
one or more of its arguments, each with its own unary filter function,
and then calling the target with each pre-processed argument
replaced by the result of its corresponding filter function. |
static MethodHandle |
foldArguments(MethodHandle target,
MethodHandle combiner)
PROVISIONAL API, WORK IN PROGRESS: Adapt a target method handle target by pre-processing
some of its arguments, and then calling the target with
the result of the pre-processing, plus all original arguments. |
static MethodHandle |
genericInvoker(MethodType type)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which will invoke any method handle of the given type on a standard set of Object type arguments. |
static MethodHandle |
guardWithTest(MethodHandle test,
MethodHandle target,
MethodHandle fallback)
PROVISIONAL API, WORK IN PROGRESS: Make a method handle which adapts a target method handle, by guarding it with a test, a boolean-valued method handle. |
static MethodHandle |
insertArgument(MethodHandle target,
int pos,
Object value)
Deprecated. |
static MethodHandle |
insertArguments(MethodHandle target,
int pos,
Object... values)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which calls the original method handle target ,
after inserting the given argument(s) at the given position. |
static Object |
invoke(MethodHandle target,
Object... arguments)
Deprecated. Alias for MethodHandle.invokeVarargs. |
static Object |
invokeVarargs(MethodHandle target,
Object... arguments)
Deprecated. Alias for MethodHandle.invokeVarargs. |
static MethodHandles.Lookup |
lookup()
Create a MethodHandles.Lookup lookup object on the caller. |
static MethodType |
methodType(Class<?> rtype)
Deprecated. |
static MethodType |
methodType(Class<?> rtype,
Class<?> ptype)
Deprecated. |
static MethodType |
methodType(Class<?> rtype,
Class<?> ptype0,
Class<?>... ptypes)
Deprecated. |
static MethodHandle |
permuteArguments(MethodHandle target,
MethodType newType,
int[] reorder)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which adapts the calling sequence of the given method handle to a new type, by reordering the arguments. |
static MethodHandles.Lookup |
publicLookup()
Version of lookup which is trusted minimally. |
static MethodHandle |
spreadArguments(MethodHandle target,
MethodType newType)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which adapts the type of the given method handle to a new type, by spreading the final argument. |
static MethodHandle |
throwException(Class<?> returnType,
Class<? extends Throwable> exType)
Produce a method handle which will throw exceptions of the given exType . |
static MethodHandle |
varargsInvoker(MethodType type,
int objectArgCount)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which will invoke any method handle of the given type on a standard set of Object type arguments
and a single trailing Object[] array. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Method Detail |
---|
public static MethodHandles.Lookup lookup()
MethodHandles.Lookup
lookup object on the caller.
public static MethodHandles.Lookup publicLookup()
public static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException
int
.
arrayClass
- an array type
IllegalArgumentException
- if arrayClass is not an array typepublic static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException
IllegalArgumentException
- if arrayClass is not an array type@Deprecated public static Object invokeVarargs(MethodHandle target, Object... arguments) throws Throwable
Throwable
@Deprecated public static Object invoke(MethodHandle target, Object... arguments) throws Throwable
Throwable
public static MethodHandle genericInvoker(MethodType type)
Object
type arguments.
The resulting invoker will be a method handle with the following
arguments:
MethodHandle
target
Object
values (one for each argument in type
)
convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
The return value of the invoker will be an Object
reference,
boxing a primitive value if the original type returns a primitive,
and always null if the original type returns void.
This method is equivalent to the following code (though it may be more efficient):
MethodHandle invoker = exactInvoker(type); MethodType genericType = type.generic(); genericType = genericType.insertParameterType(0, MethodHandle.class); return convertArguments(invoker, genericType);
type
- the type of target methods which the invoker will apply to
public static MethodHandle varargsInvoker(MethodType type, int objectArgCount)
Object
type arguments
and a single trailing Object[]
array.
The resulting invoker will be a method handle with the following
arguments:
MethodHandle
target
Object
values (counted by objectArgCount
)
Object[]
array containing more arguments
Object
reference,
boxing a primitive value if the original type returns a primitive,
and always null if the original type returns void.
This method is equivalent to the following code (though it may be more efficient):
MethodHandle invoker = exactInvoker(type); MethodType vaType = MethodType.makeGeneric(objectArgCount, true); vaType = vaType.insertParameterType(0, MethodHandle.class); return spreadArguments(invoker, vaType);
type
- the desired target typeobjectArgCount
- number of fixed (non-varargs) Object
arguments
public static MethodHandle exactInvoker(MethodType type)
MethodHandle
.
This method is equivalent to the following code (though it may be more efficient):
lookup().findVirtual(MethodHandle.class, "invoke", type);
type
- the desired target type
public static MethodHandle dynamicInvoker(CallSite site)
MethodHandles.Lookup.findVirtual(java.lang.Class>, java.lang.String, java.dyn.MethodType)
, MethodHandles.Lookup.findStatic(java.lang.Class>, java.lang.String, java.dyn.MethodType)
,
and MethodHandles.Lookup.findSpecial(java.lang.Class>, java.lang.String, java.dyn.MethodType, java.lang.Class>)
, this completes the emulation
of the JVM's invoke
instructions.
This method is equivalent to the following code:
MethodHandle getTarget, invoker, result; getTarget = lookup().bind(site, "getTarget", methodType(MethodHandle.class)); invoker = exactInvoker(site.type()); result = foldArguments(invoker, getTarget)
public static MethodHandle convertArguments(MethodHandle target, MethodType newType)
If the original type and new type are equal, returns target.
The following conversions are applied as needed both to arguments and return types. Let T0 and T1 be the differing new and old parameter types (or old and new return types) for corresponding values passed by the new and old method types. Given those types T0, T1, one of the following conversions is applied if possible:
target
- the method handle to invoke after arguments are retypednewType
- the expected type of the new method handle
target
after performing
any necessary argument conversions, and arranges for any
necessary return value conversions
IllegalArgumentException
- if the conversion cannot be madeMethodHandle.asType(java.dyn.MethodType)
public static MethodHandle permuteArguments(MethodHandle target, MethodType newType, int[] reorder)
The given array controls the reordering.
Call #I
the number of incoming parameters (the value
newType.parameterCount()
, and call #O
the number
of outgoing parameters (the value target.type().parameterCount()
).
Then the length of the reordering array must be #O
,
and each element must be a non-negative number less than #I
.
For every N
less than #O
, the N
-th
outgoing argument will be taken from the I
-th incoming
argument, where I
is reorder[N]
.
The reordering array need not specify an actual permutation. An incoming argument will be duplicated if its index appears more than once in the array, and an incoming argument will be dropped if its index does not appear in the array.
Pairwise conversions are applied as needed to arguments and return
values, as with convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
target
- the method handle to invoke after arguments are reorderednewType
- the expected type of the new method handlereorder
- a string which controls the reordering
target
after performing
any necessary argument motion and conversions, and arranges for any
necessary return value conversionspublic static MethodHandle spreadArguments(MethodHandle target, MethodType newType)
The final parameter type of the new type must be an array type T[]. This is the type of what is called the spread argument. All other arguments of the new type are called ordinary arguments.
The ordinary arguments of the new type are pairwise converted
to the initial parameter types of the old type, according to the
rules in convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
Any additional arguments in the old type
are converted from the array element type T,
again according to the rules in convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
The return value is converted according likewise.
The call verifies that the spread argument is in fact an array of exactly the type length, i.e., the excess number of arguments in the old type over the ordinary arguments in the new type. If there are no excess arguments, the spread argument is also allowed to be null.
target
- the method handle to invoke after the argument is prependednewType
- the expected type of the new method handle
public static MethodHandle collectArguments(MethodHandle target, MethodType newType)
This method may be used as an inverse to spreadArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
The final parameter type of the old type must be an array type T[],
which is the type of what is called the spread argument.
The trailing arguments of the new type which correspond to
the spread argument are all converted to type T and collected
into an array before the original method is called.
target
- the method handle to invoke after the argument is prependednewType
- the expected type of the new method handle
public static MethodHandle insertArguments(MethodHandle target, int pos, Object... values)
target
,
after inserting the given argument(s) at the given position.
The formal parameters to target
which will be supplied by those
arguments are called bound parameters, because the new method
will contain bindings for those parameters take from values
.
The type of the new method handle will drop the types for the bound
parameters from the original target type, since the new method handle
will no longer require those arguments to be supplied by its callers.
Each given argument object must match the corresponding bound parameter type. If a bound parameter type is a primitive, the argument object must be a wrapper, and will be unboxed to produce the primitive value.
The pos may range between zero and N (inclusively), where N is the number of argument types in resulting method handle (after bound parameter types are dropped).
target
- the method handle to invoke after the argument is insertedpos
- where to insert the argument (zero for the first)values
- the series of arguments to insert
@Deprecated public static MethodHandle insertArgument(MethodHandle target, int pos, Object value)
public static MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes)
The pos may range between zero and N, where N is the number of argument types in target, meaning to drop the first or last argument (respectively), or an argument somewhere in between.
Example:
MethodHandle cat = MethodHandles.lookup(). findVirtual(String.class, "concat", String.class, String.class); System.out.println(cat.<String>invoke("x", "y")); // xy MethodHandle d0 = dropArguments(cat, 0, String.class); System.out.println(d0.<String>invoke("x", "y", "z")); // xy MethodHandle d1 = dropArguments(cat, 1, String.class); System.out.println(d1.<String>invoke("x", "y", "z")); // xz MethodHandle d2 = dropArguments(cat, 2, String.class); System.out.println(d2.<String>invoke("x", "y", "z")); // yz MethodHandle d12 = dropArguments(cat, 1, String.class, String.class); System.out.println(d12.<String>invoke("w", "x", "y", "z")); // wz
target
- the method handle to invoke after the argument is droppedvalueTypes
- the type(s) of the argument to droppos
- which argument to drop (zero for the first)
public static MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes)
public static MethodHandle filterArguments(MethodHandle target, MethodHandle... filters)
target
by pre-processing
one or more of its arguments, each with its own unary filter function,
and then calling the target with each pre-processed argument
replaced by the result of its corresponding filter function.
The pre-processing is performed by one or more method handles,
specified in the non-null elements of the filters
array.
(If there are no such elements, the original target is returned.)
Each filter (that is, each non-null element of filters
)
is applied to the corresponding argument of the adapter.
If a filter F
applies to the N
th argument of
the method handle, then F
must be a method handle which
takes exactly one argument. The type of F
's sole argument
replaces the corresponding argument type of the target
in the resulting adapted method handle.
The return type of F
must be identical to the corresponding
parameter type of the target.
It is an error if there are non-null elements of filters
which do not correspond to argument positions in the target.
The actual length of the target array may be any number, it need
not be the same as the parameter count of the target type.
(This provides an easy way to filter just the first argument or two
of a target method handle.)
Here is pseudocode for the resulting adapter:
// there are N arguments in the A sequence T target(A[N]...); [i<N] V[i] filter[i](B[i]) = filters[i] ?: identity; T adapter(B[N]... b) { A[N] a...; [i<N] a[i] = filter[i](b[i]); return target(a...); }
target
- the method handle to invoke after arguments are filteredfilters
- method handles to call initially on filtered arguments
IllegalArgumentException
- if a non-null element of filters
does not match a corresponding argument type of target
public static MethodHandle foldArguments(MethodHandle target, MethodHandle combiner)
target
by pre-processing
some of its arguments, and then calling the target with
the result of the pre-processing, plus all original arguments.
The pre-processing is performed by a second method handle, the combiner
.
The first N
arguments passed to the adapter,
are copied to the combiner, which then produces a result.
(Here, N
is defined as the parameter count of the adapter.)
After this, control passes to the target
, with both the result
of the combiner, and all the original incoming arguments.
The first argument type of the target must be identical with the return type of the combiner. The resulting adapter is the same type as the target, except that the initial argument type of the target is dropped.
(Note that dropArguments(java.dyn.MethodHandle, int, java.util.List
can be used to remove any arguments
that either the combiner
or target
does not wish to receive.
If some of the incoming arguments are destined only for the combiner,
consider using collectArguments(java.dyn.MethodHandle, java.dyn.MethodType)
instead, since those
arguments will not need to be live on the stack on entry to the
target.)
The first argument of the target must be identical with the return value of the combiner.
Here is pseudocode for the resulting adapter:
// there are N arguments in the A sequence T target(V, A[N]..., B...); V combiner(A...); T adapter(A... a, B... b) { V v = combiner(a...); return target(v, a..., b...); }
target
- the method handle to invoke after arguments are combinedcombiner
- method handle to call initially on the incoming arguments
IllegalArgumentException
- if the first argument type of
target
is not the same as combiner
's return type,
or if the next foldArgs
argument types of target
are not identical with the argument types of combiner
public static MethodHandle guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback)
Here is pseudocode for the resulting adapter:
boolean test(A...); T target(A...,B...); T fallback(A...,B...); T adapter(A... a,B... b) { if (test(a...)) return target(a..., b...); else return fallback(a..., b...); }
test
- method handle used for test, must return booleantarget
- method handle to call if test passesfallback
- method handle to call if test fails
IllegalArgumentException
- if test
does not return boolean,
or if all three method types do not match (with the return
type of test
changed to match that of target
).public static MethodHandle catchException(MethodHandle target, Class<? extends Throwable> exType, MethodHandle handler)
The handler must have leading parameter of exType
or a supertype,
followed by arguments which correspond (how? TBD) to
all the parameters of the target.
The target and handler must return the same type.
Here is pseudocode for the resulting adapter:
T target(A...); T handler(ExType, A...); T adapter(A... a) { try { return target(a...); } catch (ExType ex) { return handler(ex, a...); } }
target
- method handle to callexType
- the type of exception which the handler will catchhandler
- method handle to call if a matching exception is thrown
IllegalArgumentException
- if handler
does not accept
the given exception type, or if the method handle types do
not match in their return types and their
corresponding parameterspublic static MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType)
exType
.
The method handle will accept a single argument of exType
,
and immediately throw it as an exception.
The method type will nominally specify a return of returnType
.
The return type may be anything convenient: It doesn't matter to the
method handle's behavior, since it will never return normally.
@Deprecated public static MethodType methodType(Class<?> rtype)
MethodType.methodType(java.lang.Class>, java.lang.Class>[])
.
@Deprecated public static MethodType methodType(Class<?> rtype, Class<?> ptype)
MethodType.methodType(java.lang.Class>, java.lang.Class>[])
.
@Deprecated public static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes)
MethodType.methodType(java.lang.Class>, java.lang.Class>[])
.
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |