Home » openjdk-7 » java.lang.invoke » [javadoc | source]
java.lang.invoke
public class: MethodHandles [javadoc | source]
java.lang.Object
   java.lang.invoke.MethodHandles
This class consists exclusively of static methods that operate on or return method handles. They fall into several categories:

Nested Class Summary:
public static final class  MethodHandles.Lookup  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 {@linkplain #lookupClass lookup class}.

A lookup class which needs to create method handles will call {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself. When the {@code Lookup} factory object is created, the identity of the lookup class is determined, and securely stored in the {@code Lookup} object. The lookup class (or its delegates) may then use factory methods on the {@code Lookup} object to create method handles for access-checked members. This includes all methods, constructors, and fields which are allowed to the lookup class, even private ones.

The factory methods on a {@code 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 expressionmemberbehavior
{@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)} FT f;(T) this.f;
{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)} static
FT f;
(T) C.f;
{@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)} FT f;this.f = x;
{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)} static
FT f;
C.f = arg;
{@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)} T m(A*);(T) this.m(arg*);
{@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)} static
T m(A*);
(T) C.m(arg*);
{@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)} T m(A*);(T) super.m(arg*);
{@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)} C(A*);(T) new C(arg*);
{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)} (static)?
FT f;
(FT) aField.get(thisOrNull);
{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)} (static)?
FT f;
aField.set(thisOrNull, arg);
{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)} (static)?
T m(A*);
(T) aMethod.invoke(thisOrNull, arg*);
{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)} C(A*);(C) aConstructor.newInstance(arg*);
{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)} (static)?
T m(A*);
(T) aMethod.invoke(thisOrNull, arg*);
Here, the type {@code C} is the class or interface being searched for a member, documented as a parameter named {@code refc} in the lookup methods. The method or constructor type {@code MT} is composed from the return type {@code T} and the sequence of argument types {@code A*}. Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}. The formal parameter {@code this} stands for the self-reference of type {@code C}; if it is present, it is always the leading argument to the method handle invocation. The name {@code arg} stands for all the other method handle arguments. In the code examples for the Core Reflection API, the name {@code thisOrNull} stands for a null reference if the accessed method or field is static, and {@code this} otherwise. The names {@code aMethod}, {@code aField}, and {@code aConstructor} 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 {@linkplain MethodHandle#asVarargsCollector 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 {@code 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 {@code T} or {@code MT} is not symbolically accessible from the lookup class's loader, the lookup can still succeed. For example, lookups for {@code MethodHandle.invokeExact} and {@code MethodHandle.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 {@code ldc} instruction is not subject to security manager checks.

Access checking

Access checks are applied in the factory methods of {@code Lookup}, when a method handle is created. This is a key difference from the Core Reflection API, since {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke} performs access checking against every caller, on every call.

All access checks start from a {@code Lookup} object, which compares its recorded lookup class against all requests to create method handles. A single {@code Lookup} object can be used to create any number of access-checked method handles, all checked against a single lookup class.

A {@code Lookup} object can be shared with other trusted code, such as a metaobject protocol. A shared {@code Lookup} object delegates the capability to create method handles on private members of the lookup class. Even if privileged code uses the {@code Lookup} object, the access checking is confined to the privileges of the original lookup class.

A lookup can fail, because the containing class is not accessible to the lookup class, or because the desired class member is missing, or because the desired class member is not accessible to the lookup class. In any of these cases, a {@code 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 {@code M} are exactly equivalent to the conditions under which the lookup class could have compiled and resolved a call to {@code M}. And the effect of invoking the method handle resulting from the lookup is exactly equivalent to executing the compiled and resolved call to {@code M}. The same point is true of fields and constructors.

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 {@code C.D} can access private members within other related classes such as {@code C}, {@code C.D.E}, or {@code C.B}, but the Java compiler may need to generate wrapper methods in those related classes. In such cases, a {@code Lookup} object on {@code C.E} would be unable to those private members. A workaround for this limitation is the {@link Lookup#in Lookup.in} method, which can transform a lookup on {@code C.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 {@code Class} object is available. Such cross-loader references are also possible with the Core Reflection API, and are impossible to bytecode instructions such as {@code invokestatic} or {@code getfield}. There is a {@linkplain java.lang.SecurityManager security manager API} to allow applications to check such cross-loader references. These checks apply to both the {@code MethodHandles.Lookup} API and the Core Reflection API (as found on {@link java.lang.Class Class}).

Access checks only apply to named and reflected methods, constructors, and fields. Other method handle creation methods, such as {@link MethodHandle#asType MethodHandle.asType}, do not require any access checks, and are done with static methods of {@link MethodHandles}, independently of any {@code Lookup} 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 a {@link java.lang.SecurityException SecurityException}. Define {@code smgr} as the security manager, {@code refc} as the containing class in which the member is being sought, and {@code defc} as the class in which the member is actually defined. The calls are made according to the following rules:
  • In all cases, {@link SecurityManager#checkMemberAccess 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 {@code refc}, then {@link SecurityManager#checkPackageAccess smgr.checkPackageAccess(refcPkg)} is called, where {@code refcPkg} is the package of {@code refc}.
  • If the retrieved member is not public, {@link SecurityManager#checkMemberAccess smgr.checkMemberAccess(defc, Member.DECLARED)} is called. (Note that {@code defc} might be the same as {@code refc}.) The default implementation of this security manager method inspects the stack to determine the original caller of the reflective request (such as {@code findStatic}), and performs additional permission checks if the class loader of {@code defc} differs from the class loader of the class from which the reflective request came.
  • If the retrieved member is not public, and if {@code defc} and {@code refc} 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 of {@code defc}, then {@link SecurityManager#checkPackageAccess smgr.checkPackageAccess(defcPkg)} is called, where {@code defcPkg} is the package of {@code defc}.
 
Method from java.lang.invoke.MethodHandles Summary:
arrayElementGetter,   arrayElementSetter,   catchException,   checkValue,   checkValue,   constant,   dropArguments,   dropArguments,   exactInvoker,   explicitCastArguments,   filterArgument,   filterArguments,   filterReturnValue,   foldArguments,   guardWithTest,   identity,   insertArguments,   invoker,   lookup,   misMatchedTypes,   permuteArguments,   publicLookup,   spreadInvoker,   throwException
Methods from java.lang.Object:
clone,   equals,   finalize,   getClass,   hashCode,   notify,   notifyAll,   toString,   wait,   wait,   wait
Method from java.lang.invoke.MethodHandles Detail:
 public static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException 
    Produces 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 {@code int}.
 public static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException 
    Produces 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.
 public static MethodHandle catchException(MethodHandle target,
    Class<Throwable> exType,
    MethodHandle handler) 
    Makes 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 target and handler must have the same corresponding argument and return types, except that handler may omit trailing arguments (similarly to the predicate in guardWithTest ). Also, the handler must have an extra leading parameter of {@code exType} or a supertype.

    Here is pseudocode for the resulting adapter:

    T target(A..., B...);
    T handler(ExType, A...);
    T adapter(A... a, B... b) {
      try {
        return target(a..., b...);
      } catch (ExType ex) {
        return handler(ex, a...);
      }
    }
    
    Note that the saved arguments ({@code a...} in the pseudocode) cannot be modified by execution of the target, and so are passed unchanged from the caller to the handler, if the handler is invoked.

    The target and handler must return the same type, even if the handler always throws. (This might happen, for instance, because the handler is simulating a {@code finally} clause). To create such a throwing handler, compose the handler creation logic with throwException , in order to create a method handle of the correct return type.

 static Object checkValue(Class<?> T1,
    Object value) throws ClassCastException 
 static T1 checkValue(Class<T0> t0,
    Class<T1> t1,
    Object value) throws ClassCastException 
    Perform value checking, exactly as if for an adapted method handle. It is assumed that the given value is either null, of type T0, or (if T0 is primitive) of the wrapper class corresponding to T0. The following checks and conversions are made:
    • If T0 and T1 are references, then a cast to T1 is applied. (The types do not need to be related in any particular way.)
    • If T0 and T1 are primitives, then a widening or narrowing conversion is applied, if one exists.
    • If T0 is a primitive and T1 a reference, and T0 has a wrapper class TW, a boxing conversion to TW is applied, possibly followed by a reference conversion. T1 must be TW or a supertype.
    • If T0 is a reference and T1 a primitive, and T1 has a wrapper class TW, an unboxing conversion is applied, possibly preceded by a reference conversion. T0 must be TW or a supertype.
    • If T1 is void, the return value is discarded
    • If T0 is void and T1 a reference, a null value is introduced.
    • If T0 is void and T1 a primitive, a zero value is introduced.
    If the value is discarded, null will be returned.
 public static MethodHandle constant(Class<?> type,
    Object value) 
    Produces a method handle of the requested return type which returns the given constant value every time it is invoked.

    Before the method handle is returned, the passed-in value is converted to the requested type. If the requested type is primitive, widening primitive conversions are attempted, else reference conversions are attempted.

    The returned method handle is equivalent to {@code identity(type).bindTo(value)}.

 public static MethodHandle dropArguments(MethodHandle target,
    int pos,
    List<?> valueTypes) 
    Produces a method handle which will discard some dummy arguments before calling some other specified target method handle. The type of the new method handle will be the same as the target's type, except it will also include the dummy argument types, at some given position.

    The {@code pos} argument may range between zero and N, where N is the arity of the target. If {@code pos} is zero, the dummy arguments will precede the target's real arguments; if {@code pos} is N they will come after.

    Example:

    import static java.lang.invoke.MethodHandles.*;
    import static java.lang.invoke.MethodType.*;
    ...
    MethodHandle cat = lookup().findVirtual(String.class,
    "concat", methodType(String.class, String.class));
    assertEquals("xy", (String) cat.invokeExact("x", "y"));
    MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
    MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
    assertEquals(bigType, d0.type());
    assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
    

    This method is also equivalent to the following code:

     dropArguments (target, pos, valueTypes.toArray(new Class[0]))
    
 public static MethodHandle dropArguments(MethodHandle target,
    int pos,
    Class<?> valueTypes) 
    Produces a method handle which will discard some dummy arguments before calling some other specified target method handle. The type of the new method handle will be the same as the target's type, except it will also include the dummy argument types, at some given position.

    The {@code pos} argument may range between zero and N, where N is the arity of the target. If {@code pos} is zero, the dummy arguments will precede the target's real arguments; if {@code pos} is N they will come after.

    Example:

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

    This method is also equivalent to the following code:

     dropArguments (target, pos, Arrays.asList(valueTypes))
    
 public static MethodHandle exactInvoker(MethodType type) 
    Produces a special invoker method handle which can be used to invoke any method handle of the given type, as if by invokeExact . 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 {@code MethodHandle}.

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

    publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
    

    Discussion: Invoker method handles can be useful when working with variable method handles of unknown types. For example, to emulate an {@code invokeExact} call to a variable method handle {@code M}, extract its type {@code T}, look up the invoker method {@code X} for {@code T}, and call the invoker method, as {@code X.invoke(T, A...)}. (It would not work to call {@code X.invokeExact}, since the type {@code T} is unknown.) If spreading, collecting, or other argument transformations are required, they can be applied once to the invoker {@code X} and reused on many {@code M} method handle values, as long as they are compatible with the type of {@code X}.

    (Note: The invoker method is not available via the Core Reflection API. An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke} on the declared {@code invokeExact} or {@code invoke} method will raise an UnsupportedOperationException .)

    This method throws no reflective or security exceptions.

 public static MethodHandle explicitCastArguments(MethodHandle target,
    MethodType newType) 
    Produces a method handle which adapts the type of the given method handle to a new type by pairwise argument and return type conversion. The original type and new type must have the same number of arguments. The resulting method handle is guaranteed to report a type which is equal to the desired new type.

    If the original type and new type are equal, returns target.

    The same conversions are allowed as for MethodHandle.asType , and some additional conversions are also applied if those conversions fail. Given types T0, T1, one of the following conversions is applied if possible, before or instead of any conversions done by {@code asType}:

    • If T0 and T1 are references, and T1 is an interface type, then the value of type T0 is passed as a T1 without a cast. (This treatment of interfaces follows the usage of the bytecode verifier.)
    • If T0 is boolean and T1 is another primitive, the boolean is converted to a byte value, 1 for true, 0 for false. (This treatment follows the usage of the bytecode verifier.)
    • If T1 is boolean and T0 is another primitive, T0 is converted to byte via Java casting conversion (JLS 5.5), and the low order bit of the result is tested, as if by {@code (x & 1) != 0}.
    • If T0 and T1 are primitives other than boolean, then a Java casting conversion (JLS 5.5) is applied. (Specifically, T0 will convert to T1 by widening and/or narrowing.)
    • If T0 is a reference and T1 a primitive, an unboxing conversion will be applied at runtime, possibly followed by a Java casting conversion (JLS 5.5) on the primitive value, possibly followed by a conversion from byte to boolean by testing the low-order bit.
    • If T0 is a reference and T1 a primitive, and if the reference is null at runtime, a zero value is introduced.
 static MethodHandle filterArgument(MethodHandle target,
    int pos,
    MethodHandle filter) 
 public static MethodHandle filterArguments(MethodHandle target,
    int pos,
    MethodHandle filters) 
    Adapts a target method handle 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 elements of the {@code filters} array. The first element of the filter array corresponds to the {@code pos} argument of the target, and so on in sequence.

    Null arguments in the array are treated as identity functions, and the corresponding arguments left unchanged. (If there are no non-null elements in the array, the original target is returned.) Each filter is applied to the corresponding argument of the adapter.

    If a filter {@code F} applies to the {@code N}th argument of the target, then {@code F} must be a method handle which takes exactly one argument. The type of {@code F}'s sole argument replaces the corresponding argument type of the target in the resulting adapted method handle. The return type of {@code F} must be identical to the corresponding parameter type of the target.

    It is an error if there are elements of {@code filters} (null or not) which do not correspond to argument positions in the target. Example:

    import static java.lang.invoke.MethodHandles.*;
    import static java.lang.invoke.MethodType.*;
    ...
    MethodHandle cat = lookup().findVirtual(String.class,
    "concat", methodType(String.class, String.class));
    MethodHandle upcase = lookup().findVirtual(String.class,
    "toUpperCase", methodType(String.class));
    assertEquals("xy", (String) cat.invokeExact("x", "y"));
    MethodHandle f0 = filterArguments(cat, 0, upcase);
    assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
    MethodHandle f1 = filterArguments(cat, 1, upcase);
    assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
    MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
    assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
    

    Here is pseudocode for the resulting adapter:

    V target(P... p, A[i]... a[i], B... b);
    A[i] filter[i](V[i]);
    T adapter(P... p, V[i]... v[i], B... b) {
      return target(p..., f[i](v[i])..., b...);
    }
    
 public static MethodHandle filterReturnValue(MethodHandle target,
    MethodHandle filter) 
    Adapts a target method handle by post-processing its return value (if any) with a filter (another method handle). The result of the filter is returned from the adapter.

    If the target returns a value, the filter must accept that value as its only argument. If the target returns void, the filter must accept no arguments.

    The return type of the filter replaces the return type of the target in the resulting adapted method handle. The argument type of the filter (if any) must be identical to the return type of the target. Example:

    import static java.lang.invoke.MethodHandles.*;
    import static java.lang.invoke.MethodType.*;
    ...
    MethodHandle cat = lookup().findVirtual(String.class,
    "concat", methodType(String.class, String.class));
    MethodHandle length = lookup().findVirtual(String.class,
    "length", methodType(int.class));
    System.out.println((String) cat.invokeExact("x", "y")); // xy
    MethodHandle f0 = filterReturnValue(cat, length);
    System.out.println((int) f0.invokeExact("x", "y")); // 2
    

    Here is pseudocode for the resulting adapter:

    V target(A...);
    T filter(V);
    T adapter(A... a) {
      V v = target(a...);
      return filter(v);
    }
    // and if the target has a void return:
    void target2(A...);
    T filter2();
    T adapter2(A... a) {
      target2(a...);
      return filter2();
    }
    // and if the filter has a void return:
    V target3(A...);
    void filter3(V);
    void adapter3(A... a) {
      V v = target3(a...);
      filter3(v);
    }
    
 public static MethodHandle foldArguments(MethodHandle target,
    MethodHandle combiner) 
    Adapts a target method handle by pre-processing some of its arguments, and then calling the target with the result of the pre-processing, inserted into the original sequence of arguments.

    The pre-processing is performed by {@code combiner}, a second method handle. Of the arguments passed to the adapter, the first {@code N} arguments are copied to the combiner, which is then called. (Here, {@code N} is defined as the parameter count of the combiner.) After this, control passes to the target, with any result from the combiner inserted before the original {@code N} incoming arguments.

    If the combiner returns a value, the first parameter type of the target must be identical with the return type of the combiner, and the next {@code N} parameter types of the target must exactly match the parameters of the combiner.

    If the combiner has a void return, no result will be inserted, and the first {@code N} parameter types of the target must exactly match the parameters of the combiner.

    The resulting adapter is the same type as the target, except that the first parameter type is dropped, if it corresponds to the result of the combiner.

    (Note that dropArguments can be used to remove any arguments that either the combiner or the target does not wish to receive. If some of the incoming arguments are destined only for the combiner, consider using asCollector instead, since those arguments will not need to be live on the stack on entry to the target.) Example:

    import static java.lang.invoke.MethodHandles.*;
    import static java.lang.invoke.MethodType.*;
    ...
    MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
    "println", methodType(void.class, String.class))
    .bindTo(System.out);
    MethodHandle cat = lookup().findVirtual(String.class,
    "concat", methodType(String.class, String.class));
    assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
    MethodHandle catTrace = foldArguments(cat, trace);
    // also prints "boo":
    assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
    

    Here is pseudocode for the resulting adapter:

    // there are N arguments in A...
    T target(V, A[N]..., B...);
    V combiner(A...);
    T adapter(A... a, B... b) {
      V v = combiner(a...);
      return target(v, a..., b...);
    }
    // and if the combiner has a void return:
    T target2(A[N]..., B...);
    void combiner2(A...);
    T adapter2(A... a, B... b) {
      combiner2(a...);
      return target2(a..., b...);
    }
    
 public static MethodHandle guardWithTest(MethodHandle test,
    MethodHandle target,
    MethodHandle fallback) 
    Makes 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...);
    }
    
    Note that the test arguments ({@code a...} in the pseudocode) cannot be modified by execution of the test, and so are passed unchanged from the caller to the target or fallback as appropriate.
 public static MethodHandle identity(Class<?> type) 
    Produces a method handle which returns its sole argument when invoked.
 public static MethodHandle insertArguments(MethodHandle target,
    int pos,
    Object values) 
    Provides a target method handle with one or more bound arguments in advance of the method handle's invocation. The formal parameters to the target corresponding to the bound arguments are called bound parameters. Returns a new method handle which saves away the bound arguments. When it is invoked, it receives arguments for any non-bound parameters, binds the saved arguments to their corresponding parameters, and calls the original target.

    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 {@code pos} argument selects which parameters are to be bound. It may range between zero and N-L (inclusively), where N is the arity of the target method handle and L is the length of the values array.

 public static MethodHandle invoker(MethodType type) 
    Produces a special invoker method handle which can be used to invoke any method handle compatible with the given type, as if by invoke . 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 {@code MethodHandle}.

    Before invoking its target, if the target differs from the expected type, the invoker will apply reference casts as necessary and box, unbox, or widen primitive values, as if by asType . Similarly, the return value will be converted as necessary. If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle}, the required arity conversion will be made, again as if by asType .

    A {@linkplain MethodType#genericMethodType general method type}, mentions only {@code Object} arguments and return values. An invoker for such a type is capable of calling any method handle of the same arity as the general type.

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

    publicLookup().findVirtual(MethodHandle.class, "invoke", type)
    

    This method throws no reflective or security exceptions.

 public static Lookup lookup() 
    Returns 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.
 static RuntimeException misMatchedTypes(String what,
    MethodType t1,
    MethodType t2) 
 public static MethodHandle permuteArguments(MethodHandle target,
    MethodType newType,
    int reorder) 
    Produces 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 report a type which is equal to the desired new type.

    The given array controls the reordering. Call {@code #I} the number of incoming parameters (the value {@code newType.parameterCount()}, and call {@code #O} the number of outgoing parameters (the value {@code target.type().parameterCount()}). Then the length of the reordering array must be {@code #O}, and each element must be a non-negative number less than {@code #I}. For every {@code N} less than {@code #O}, the {@code N}-th outgoing argument will be taken from the {@code I}-th incoming argument, where {@code I} is {@code reorder[N]}.

    No argument or return value conversions are applied. The type of each incoming argument, as determined by {@code newType}, must be identical to the type of the corresponding outgoing parameter or parameters in the target method handle. The return type of {@code newType} must be identical to the return type of the original target.

    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. As in the case of dropArguments , incoming arguments which are not mentioned in the reordering array are may be any type, as determined only by {@code newType}.

    import static java.lang.invoke.MethodHandles.*;
    import static java.lang.invoke.MethodType.*;
    ...
    MethodType intfn1 = methodType(int.class, int.class);
    MethodType intfn2 = methodType(int.class, int.class, int.class);
    MethodHandle sub = ... {int x, int y => x-y} ...;
    assert(sub.type().equals(intfn2));
    MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
    MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
    assert((int)rsub.invokeExact(1, 100) == 99);
    MethodHandle add = ... {int x, int y => x+y} ...;
    assert(add.type().equals(intfn2));
    MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
    assert(twice.type().equals(intfn1));
    assert((int)twice.invokeExact(21) == 42);
    
 public static Lookup publicLookup() 
    Returns 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 {@linkplain Lookup#lookupClass lookup class} of this lookup object will be java.lang.Object .

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

 public static MethodHandle spreadInvoker(MethodType type,
    int leadingArgCount) 
    Produces a method handle which will invoke any method handle of the given {@code type}, with a given number of trailing arguments replaced by a single trailing {@code Object[]} array. The resulting invoker will be a method handle with the following arguments:
    • a single {@code MethodHandle} target
    • zero or more leading values (counted by {@code leadingArgCount})
    • an {@code Object[]} array containing trailing arguments

    The invoker will invoke its target like a call to invoke with the indicated {@code type}. That is, if the target is exactly of the given {@code type}, it will behave like {@code invokeExact}; otherwise it behave as if asType is used to convert the target to the required {@code type}.

    The type of the returned invoker will not be the given {@code type}, but rather will have all parameters except the first {@code leadingArgCount} replaced by a single array of type {@code Object[]}, which will be the final parameter.

    Before invoking its target, the invoker will spread the final array, apply reference casts as necessary, and unbox and widen primitive arguments.

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

    MethodHandle invoker = MethodHandles.invoker(type);
    int spreadArgCount = type.parameterCount() - leadingArgCount;
    invoker = invoker.asSpreader(Object[].class, spreadArgCount);
    return invoker;
    

    This method throws no reflective or security exceptions.

 public static MethodHandle throwException(Class<?> returnType,
    Class<Throwable> exType) 
    Produces a method handle which will throw exceptions of the given {@code exType}. The method handle will accept a single argument of {@code exType}, and immediately throw it as an exception. The method type will nominally specify a return of {@code returnType}. The return type may be anything convenient: It doesn't matter to the method handle's behavior, since it will never return normally.