Spec-Zone .ru
спецификации, руководства, описания, API
Please note that the specifications and other information contained herein are not final and are subject to change. The information is being made available to you solely for purpose of evaluation.

Java™ Platform
Standard Ed. 7

DRAFT ea-b118

java.dyn
Class MethodHandles

java.lang.Object
  extended by java.dyn.MethodHandles

public class MethodHandles
extends Object

This class consists exclusively of static methods that operate on or return method handles. They fall into several categories:


Nested Class Summary
Modifier and Type Class and Description
static class MethodHandles.Lookup
          A lookup object is a factory for creating method handles, when the creation requires access checking.
 
Method Summary
Modifier and Type Method and Description
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
<T> T
asInstance(MethodHandle target, Class<T> samType)
          Produce a wrapper instance of the given "SAM" type which redirects its calls to the given method handle.
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()
          Return a lookup object on the caller, which has the capability to access any method handle that the caller has access to, including direct method handles to private fields and methods.
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()
          Return a lookup object 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

lookup

public static MethodHandles.Lookup lookup()
Return a lookup object on the caller, which has the capability to access any method handle that the caller has access to, including direct method handles to private fields and methods. This lookup object is a capability which may be delegated to trusted agents. Do not store it in place where untrusted code can access it.


publicLookup

public static MethodHandles.Lookup publicLookup()
Return a lookup object which is trusted minimally. It can only be used to create method handles to publicly accessible fields and methods.

As a matter of pure convention, the lookup class of this lookup object will be Object.

The lookup class can be changed to any other class C using an expression of the form publicLookup().in(C.class). Since all classes have equal access to public names, such a change would confer no new access rights.


arrayElementGetter

public static MethodHandle arrayElementGetter(Class<?> arrayClass)
                                       throws IllegalArgumentException
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle giving read access to elements of an array. The type of the method handle will have a return type of the array's element type. Its first argument will be the array type, and the second will be int.

Parameters:
arrayClass - an array type
Returns:
a method handle which can load values from the given array type
Throws:
IllegalArgumentException - if arrayClass is not an array type

arrayElementSetter

public static MethodHandle arrayElementSetter(Class<?> arrayClass)
                                       throws IllegalArgumentException
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle giving write access to elements of an array. The type of the method handle will have a void return type. Its last argument will be the array's element type. The first and second arguments will be the array type and int.

Returns:
a method handle which can store values into the array type
Throws:
IllegalArgumentException - if arrayClass is not an array type

invokeVarargs

@Deprecated
public static Object invokeVarargs(MethodHandle target,
                                              Object... arguments)
                            throws Throwable
Deprecated. Alias for MethodHandle.invokeVarargs.

Throws:
Throwable

invoke

@Deprecated
public static Object invoke(MethodHandle target,
                                       Object... arguments)
                     throws Throwable
Deprecated. Alias for MethodHandle.invokeVarargs.

Throws:
Throwable

genericInvoker

public 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. The resulting invoker will be a method handle with the following arguments: The invoker will apply reference casts as necessary and unbox primitive arguments, as if by 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);
 

Parameters:
type - the type of target methods which the invoker will apply to
Returns:
a method handle suitable for invoking any method handle of the given type

varargsInvoker

public 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. The resulting invoker will be a method handle with the following arguments: The invoker will spread the varargs array, apply reference casts as necessary, and unbox primitive arguments. 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 vaType = MethodType.makeGeneric(objectArgCount, true);
 vaType = vaType.insertParameterType(0, MethodHandle.class);
 return spreadArguments(invoker, vaType);
 

Parameters:
type - the desired target type
objectArgCount - number of fixed (non-varargs) Object arguments
Returns:
a method handle suitable for invoking any method handle of the given type

exactInvoker

public 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. The resulting invoker will have a type which is exactly equal to the desired type, except that it will accept an additional leading argument of type MethodHandle.

This method is equivalent to the following code (though it may be more efficient):

 lookup().findVirtual(MethodHandle.class, "invoke", type);
 

Parameters:
type - the desired target type
Returns:
a method handle suitable for invoking any method handle of the given type

dynamicInvoker

public static MethodHandle dynamicInvoker(CallSite site)
                                   throws NoAccessException
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle equivalent to an invokedynamic instruction which has been linked to the given call site. Along with 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)
 

Returns:
a method handle which always invokes the call site's target
Throws:
NoAccessException

convertArguments

public 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. The original type and new type must have the same number of arguments. The resulting method handle is guaranteed to confess a type which is equal to the desired new type.

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:

Parameters:
target - the method handle to invoke after arguments are retyped
newType - the expected type of the new method handle
Returns:
a method handle which delegates to target after performing any necessary argument conversions, and arranges for any necessary return value conversions
Throws:
IllegalArgumentException - if the conversion cannot be made
See Also:
MethodHandle.asType(java.dyn.MethodType)

permuteArguments

public 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. The resulting method handle is guaranteed to confess a type which is equal to the desired new type.

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).

Parameters:
target - the method handle to invoke after arguments are reordered
newType - the expected type of the new method handle
reorder - a string which controls the reordering
Returns:
a method handle which delegates to target after performing any necessary argument motion and conversions, and arranges for any necessary return value conversions

spreadArguments

public 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. The resulting method handle is guaranteed to confess a type which is equal to the desired new type.

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.

Parameters:
target - the method handle to invoke after the argument is prepended
newType - the expected type of the new method handle
Returns:
a new method handle which spreads its final argument, before calling the original method handle

collectArguments

public 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.

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.

Parameters:
target - the method handle to invoke after the argument is prepended
newType - the expected type of the new method handle
Returns:
a new method handle which collects some trailing argument into an array, before calling the original method handle

insertArguments

public 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. 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).

Parameters:
target - the method handle to invoke after the argument is inserted
pos - where to insert the argument (zero for the first)
values - the series of arguments to insert
Returns:
a new method handle which inserts an additional argument, before calling the original method handle

insertArgument

@Deprecated
public static MethodHandle insertArgument(MethodHandle target,
                                                     int pos,
                                                     Object value)
Deprecated. 


dropArguments

public 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. The type of the new method handle will insert the given argument type(s), at that position, into the original handle's type.

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:

   import static java.dyn.MethodHandles.*;
   import static java.dyn.MethodType.*;
   ...
   MethodHandle cat = lookup().findVirtual(String.class,
     "concat", methodType(String.class, String.class));
   System.out.println((String) cat.invokeExact("x", "y")); // xy
   MethodHandle d0 = dropArguments(cat, 0, String.class);
   System.out.println((String) d0.invokeExact("x", "y", "z")); // yz
   MethodHandle d1 = dropArguments(cat, 1, String.class);
   System.out.println((String) d1.invokeExact("x", "y", "z")); // xz
   MethodHandle d2 = dropArguments(cat, 2, String.class);
   System.out.println((String) d2.invokeExact("x", "y", "z")); // xy
   MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
   System.out.println((String) d12.invokeExact("x", 12, true, "z")); // xz
 

Parameters:
target - the method handle to invoke after the argument is dropped
valueTypes - the type(s) of the argument to drop
pos - which argument to drop (zero for the first)
Returns:
a new method handle which drops an argument of the given type, before calling the original method handle

dropArguments

public static MethodHandle dropArguments(MethodHandle target,
                                         int pos,
                                         Class<?>... valueTypes)

filterArguments

public 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.

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 Nth 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...);
 }
 

Parameters:
target - the method handle to invoke after arguments are filtered
filters - method handles to call initially on filtered arguments
Returns:
method handle which incorporates the specified argument filtering logic
Throws:
IllegalArgumentException - if a non-null element of filters does not match a corresponding argument type of target

foldArguments

public 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.

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...);
 }
 

Parameters:
target - the method handle to invoke after arguments are combined
combiner - method handle to call initially on the incoming arguments
Returns:
method handle which incorporates the specified argument folding logic
Throws:
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

guardWithTest

public 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. If the guard fails, a fallback handle is called instead. All three method handles must have the same corresponding argument and return types, except that the return type of the test must be boolean, and the test is allowed to have fewer arguments than the other two method handles.

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...);
 }
 

Parameters:
test - method handle used for test, must return boolean
target - method handle to call if test passes
fallback - method handle to call if test fails
Returns:
method handle which incorporates the specified if/then/else logic
Throws:
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).

catchException

public 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. If the target returns normally, the adapter returns that value. If an exception matching the specified type is thrown, the fallback handle is called instead on the exception, plus the original arguments.

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...);
   }
 }
 

Parameters:
target - method handle to call
exType - the type of exception which the handler will catch
handler - method handle to call if a matching exception is thrown
Returns:
method handle which incorporates the specified try/catch logic
Throws:
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 parameters

throwException

public static MethodHandle throwException(Class<?> returnType,
                                          Class<? extends Throwable> exType)
Produce a method handle which will throw exceptions of the given 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.


asInstance

public static <T> T asInstance(MethodHandle target,
                               Class<T> samType)
Produce a wrapper instance of the given "SAM" type which redirects its calls to the given method handle. A SAM type is a type which declares a single abstract method. Additionally, it must have either no constructor (as an interface) or have a public or protected constructor of zero arguments (as a class).

The resulting instance of the required SAM type will respond to invocation of the SAM type's single abstract method by calling the given target on the incoming arguments, and returning or throwing whatever the target returns or throws. The invocation will be as if by target.invokeExact.

The method handle may throw an undeclared exception, which means any checked exception (or other checked throwable) not declared by the SAM type's single abstract method. If this happens, the throwable will be wrapped in an instance of UndeclaredThrowableException and thrown in that wrapped form.

The wrapper instance is guaranteed to be of a non-public implementation class C in a package containing no classes or methods except system-defined classes and methods. The implementation class C will have no public supertypes or public methods beyond the following:

No stable mapping is promised between the SAM type and the implementation class C. Over time, several implementation classes might be used for the same SAM type.

This method is not guaranteed to return a distinct wrapper object for each separate call. If the JVM is able to prove that a wrapper has already been created for a given method handle, or for another method handle with the same behavior, the JVM may return that wrapper in place of a new wrapper.

Parameters:
target - the method handle to invoke from the wrapper
samType - the desired type of the wrapper, a SAM type
Returns:
a correctly-typed wrapper for the given target
Throws:
IllegalArgumentException - if the target throws an undeclared exception

Java™ Platform
Standard Ed. 7

DRAFT ea-b118

Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.

Copyright © 1993, 2010, Oracle Corporation. All rights reserved.
DRAFT ea-b118

Scripting on this page tracks web page traffic, but does not change the content in any way.