Please note that this documentation is not final and is subject to change.

Java™ Platform
Standard Ed. 7

DRAFT ea-b76

java.dyn
Class MethodHandles

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

public class MethodHandles
extends Object

Fundamental operations and utilities for MethodHandle.

API Note: The matching of method types in this API cannot be completely checked by Java's generic type system for three reasons:

  1. Method types range over all possible arities, from no arguments to an arbitrary number of arguments. Generics are not variadic, and so cannot represent this.
  2. Method types can specify arguments of primitive types, which Java generic types cannot range over.
  3. Method types can optionally specify varargs (ellipsis).


Nested Class Summary
Modifier and Type Class and Description
static class MethodHandles.Lookup
          PROVISIONAL API, WORK IN PROGRESS: A factory object 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 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 into an array.
static MethodHandle combineArguments(MethodHandle target, int pos, MethodHandle combiner)
          PROVISIONAL API, WORK IN PROGRESS: Adapt a target method handle target by first processing its arguments, and then calling the target.
static MethodHandle convertArguments(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 pairwise argument conversion, and/or varargs conversion.
static MethodHandle dropArguments(MethodHandle target, int pos, 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 exactInvoker(MethodType type)
          PROVISIONAL API, WORK IN PROGRESS: Give a method handle which will take a invoke any method handle of the given type.
static MethodHandle genericInvoker(MethodType type, int objectArgCount, boolean varargs)
          PROVISIONAL API, WORK IN PROGRESS: Give 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)
          PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which calls the original method handle, after inserting the given argument at the given position.
static Object invoke_0(MethodHandle target)
           
static Object invoke_1(MethodHandle target, Object a0)
           
static Object invoke_2(MethodHandle target, Object a0, Object a1)
           
static Object invoke_3(MethodHandle target, Object a0, Object a1, Object a2)
           
static Object invoke_4(MethodHandle target, Object a0, Object a1, Object a2, Object a3)
           
static Object invoke(MethodHandle target, Object... arguments)
          PROVISIONAL API, WORK IN PROGRESS: Call the invoke method of a given method handle, with arguments that exactly match the parameter types of the method handle.
static MethodHandles.Lookup lookup()
           
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 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.
 
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()

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

invoke

public static Object invoke(MethodHandle target,
                            Object... arguments)
PROVISIONAL API, WORK IN PROGRESS: Call the invoke method of a given method handle, with arguments that exactly match the parameter types of the method handle. The length of the arguments array must equal the parameter count of the target's type. The arguments array is spread into separate arguments, and basic reference and unboxing conversions are applied.

In order to match the type of the target, the following argument conversions are applied as necessary:

The following conversions are not applied: The result returned by the call is boxed if it is a primitive, or forced to null if the return type is void.

This call is a convenience method for the following code:

   MethodHandle invoker = MethodHandles.genericInvoker(target.type(), 0, true);
   Object result = invoker.invoke(arguments);
 

Parameters:
target - the method handle to invoke
arguments - the arguments to pass to the target
Returns:
the result returned by the target

invoke_0

public static Object invoke_0(MethodHandle target)

invoke_1

public static Object invoke_1(MethodHandle target,
                              Object a0)

invoke_2

public static Object invoke_2(MethodHandle target,
                              Object a0,
                              Object a1)

invoke_3

public static Object invoke_3(MethodHandle target,
                              Object a0,
                              Object a1,
                              Object a2)

invoke_4

public static Object invoke_4(MethodHandle target,
                              Object a0,
                              Object a1,
                              Object a2,
                              Object a3)

genericInvoker

public static MethodHandle genericInvoker(MethodType type,
                                          int objectArgCount,
                                          boolean varargs)
PROVISIONAL API, WORK IN PROGRESS: Give a method handle which will invoke any method handle of the given type on a standard set of Object type arguments. The the resulting invoker will be a method handle with the following arguments: The invoker will spread the varargs array (if present), 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 is a convenience method equivalent to the following code:

 MethodHandle invoker = exactInvoker(type);
 MethodType genericType = MethodType.makeGeneric(objectArgCount, varargs);
 genericType = genericType.insertParameterType(0, MethodHandle.class);
 if (!varargs)
     return convertArguments(invoker, genericType);
 else
     return spreadArguments(invoker, genericType);
 

Parameters:
type - the desired target type
objectArgCount - number of fixed (non-varargs) Object arguments
varargs - if true, the invoker will accept a final Object[] argument
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: Give 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 is a convenience method equivalent to the following code:

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

convertArguments

public static MethodHandle convertArguments(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 pairwise argument conversion, and/or varargs conversion. The original type and new type must have the same number of arguments, or else one or both them the must be varargs types. The resulting method handle is guaranteed to confess a type which is equal to the desired new type, with any varargs property erased.

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.

If an ordinary (non-varargs) parameter of the new type is to be boxed in a varargs parameter of the old type of type T1[], then T1 is the element type of the varargs array. Otherwise, if a varargs parameter of the new type of type T0[] is to be spread into one or more outgoing old type parameters, then T0 is the element type of the If the new type is varargs and the old type is not, the varargs argument will be checked and must be a non-null array of exactly the right length. If there are no parameters in the old type corresponding to the new varargs parameter, the varargs argument is also allowed to be null.

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:
WrongMethodTypeException - if the conversion cannot be made

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

This method is 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.

ISSUE: Unify this with combineArguments. CollectArguments is combineArguments with (a) new Object[]{...} as a combiner, and (b) the combined arguments dropped, in favor of the combined result.

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 trailings argument into an array, before calling the original method handle

insertArgument

public static MethodHandle insertArgument(MethodHandle target,
                                          int pos,
                                          Object value)
PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which calls the original method handle, after inserting the given argument at the given position. The type of the new method handle will drop the corresponding argument type from the original handle's type.

The given argument object must match the dropped argument type. If the dropped argument type is a primitive, the argument object must be a wrapper, and is unboxed to produce the primitive.

The pos may range between zero and N (inclusively), where N is the number of argument types in target, meaning to insert the new argument as the first or last (respectively), or somewhere in between.

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

dropArguments

public static MethodHandle dropArguments(MethodHandle target,
                                         int pos,
                                         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-1, 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.

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

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.

Here is pseudocode for the resulting adapter:

 signature T(A...);
 boolean test(A...);
 T target(A...);
 T fallback(A...);
 T adapter(A... a) {
   if (test(a...))
     return target(a...);
   else
     return fallback(a...);
 }
 

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

combineArguments

public static MethodHandle combineArguments(MethodHandle target,
                                            int pos,
                                            MethodHandle combiner)
PROVISIONAL API, WORK IN PROGRESS: Adapt a target method handle target by first processing its arguments, and then calling the target. The initial processing is performed by a second method handle, the combiner. After this, control passes to the target, with the same arguments.

The return value of the combiner is inserted into the argument list for the target at the indicated position pos, if it is non-negative. Except for this inserted argument (if any), the argument types of the target target and the combiner must be identical.

(Note that dropArguments(java.dyn.MethodHandle, int, java.lang.Class...) can be used to remove any arguments that either the combiner or target does not wish to receive.)

The combiner handle must have the same argument types as the target handle, but must return MethodHandle instead of the ultimate return type. The returned method handle, in turn, is required to have exactly the given final method type.

Here is pseudocode for the resulting adapter:

 signature V(A[pos]..., B...);
 signature T(A[pos]..., V, B...);
 T target(A... a, V v, B... b);
 V combiner(A..., B...);
 T adapter(A... a, B... b) {
   V v = combiner(a..., b...);
   return target(a..., v, b...);
 }
 

Parameters:
target - the method handle to invoke after arguments are combined
pos - where the return value of combiner is to be inserted as an argument to target
combiner - method handle to call initially on the incoming arguments
Returns:
method handle which incorporates the specified dispatch logic
Throws:
IllegalArgumentException - if combiner does not itself return either void or the pos-th argument of target, or does not have the same argument types as target (minus the inserted argument)

Java™ Platform
Standard Ed. 7

DRAFT ea-b76

Submit a bug or feature

Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.