java.dyn
Class MethodHandle

java.lang.Object
  extended by sun.dyn.MethodHandleImpl
      extended by java.dyn.MethodHandle
Direct Known Subclasses:
sun.dyn.BoundMethodHandle

public abstract class MethodHandle
extends sun.dyn.MethodHandleImpl

Disabled: no SafeJ information.

A method handle is a typed reference to the entry point of a method.

Method handles are strongly typed according to signature. They are not distinguished by method name or enclosing class. A method handle must be invoked under a signature which exactly matches the method handle's own type.

Every method handle confesses its type via the type accessor. The structure of this type is a series of classes, one of which is the return type of the method (or void.class if none).

Every method handle appears as an object containing a method named invoke, whose signature exactly matches the method handle's type. A Java method call expression, which compiles to an invokevirtual instruction, can invoke this method from Java source code.

Every call to a method handle specifies an intended method type, which must exactly match the type of the method handle. (The type is specified in the invokevirtual instruction, via a CONSTANT_NameAndType constant pool entry.) The call looks within the receiver object for a method named invoke of the intended method type. The call fails with a WrongMethodTypeException if the method does not exist, even if there is an invoke method of a closely similar signature. As with other kinds of methods in the JVM, signature matching during method linkage is exact, and does not allow for language-level implicit conversions such as String to Object or short to int.

A method handle is an unrestricted capability to call a method. A method handle can be formed on a non-public method by a class that has access to that method; the resulting handle can be used in any place by any caller who receives a reference to it. Thus, access checking is performed when the method handle is created, not (as in reflection) every time it is called. Handles to non-public methods, or in non-public classes, should generally be kept secret. They should not be passed to untrusted code.

Bytecode in an extended JVM can directly call a method handle's invoke from an invokevirtual instruction. The receiver class type must be MethodHandle and the method name must be invoke. The signature of the invocation (after resolving symbolic type names) must exactly match the method type of the target method.

Every invoke method always throws Exception, which is to say that there is no static restriction on what a method handle can throw. Since the JVM does not distinguish between checked and unchecked exceptions (other than by their class, of course), there is no particular effect on bytecode shape from ascribing checked exceptions to method handle invocations. But in Java source code, methods which perform method handle calls must either explicitly throw Exception, or else must catch all checked exceptions locally.

Bytecode in an extended JVM can directly obtain a method handle for any accessible method from a ldc instruction which refers to a CONSTANT_Methodref or CONSTANT_InterfaceMethodref constant pool entry.

All JVMs can also use a reflective API called MethodHandles for creating and calling method handles.

A method reference may refer either to a static or non-static method. In the non-static case, the method handle type includes an explicit receiver argument, prepended before any other arguments. In the method handle's type, the initial receiver argument is typed according to the class under which the method was initially requested. (E.g., if a non-static method handle is obtained via ldc, the type of the receiver is the class named in the constant pool entry.)

When a method handle to a virtual method is invoked, the method is always looked up in the receiver (that is, the first argument).

A non-virtual method handles to a specific virtual method implementation can also be created. These do not perform virtual lookup based on receiver type. Such a method handle simulates the effect of an invokespecial instruction to the same method.

Here are some examples of usage:

 Object x, y; String s; int i;
 MethodType mt; MethodHandle mh;
 MethodHandles.Lookup lookup = MethodHandles.lookup();
 // mt is {(char,char) => String}
 mt = MethodType.make(String.class, char.class, char.class);
 mh = lookup.findVirtual(String.class, "replace", mt);
 // (Ljava/lang/String;CC)Ljava/lang/String;
 s = mh.<String>invoke("daddy",'d','n');
 assert(s.equals("nanny"));
 // weakly typed invocation (using MHs.invoke)
 s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v');
 assert(s.equals("savvy"));
 // mt is {Object[] => List}
 mt = MethodType.make(java.util.List.class, Object[].class);
 mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
 // mt is {(Object,Object,Object) => Object}
 mt = MethodType.makeGeneric(3);
 mh = MethodHandles.collectArguments(mh, mt);
 // mt is {(Object,Object,Object) => Object}
 // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 x = mh.invoke((Object)1, (Object)2, (Object)3);
 assert(x.equals(java.util.Arrays.asList(1,2,3)));
 // mt is { => int}
 mt = MethodType.make(int.class);
 mh = lookup.findVirtual(java.util.List.class, "size", mt);
 // (Ljava/util/List;)I
 i = mh.<int>invoke(java.util.Arrays.asList(1,2,3));
 assert(i == 3);
 
Each of the above calls generates a single invokevirtual instruction with the name invoke and the type descriptors indicated in the comments. The argument types are taken directly from the actual arguments, while the return type is taken from the type parameter. (This type parameter may be a primitive, and it defaults to Object.)

A note on generic typing: Method handles do not represent their function types in terms of Java parameterized (generic) types, because there are three mismatches between function types and parameterized Java types.

  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. Higher order functions over method handles (combinators) are often generic across a wide range of function types, including those of multiple arities. It is impossible to represent such genericity with a Java type parameter.

See Also:
MethodType, MethodHandles

Nested Class Summary
 
Nested classes/interfaces inherited from class sun.dyn.MethodHandleImpl
sun.dyn.MethodHandleImpl.MethodHandleFriend
 
Field Summary
 
Fields inherited from class sun.dyn.MethodHandleImpl
vmtarget
 
Constructor Summary
protected MethodHandle(sun.dyn.Access token, MethodType type)
          The constructor for MethodHandle may only be called by privileged code.
 
Method Summary
 MethodHandle asCollector(int spreadArrayArgs)
          Deprecated. Provisional and unstable; use MethodHandles.collectArguments(java.dyn.MethodHandle, java.dyn.MethodType).
 MethodHandle asSpreader(int keepPosArgs)
          PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which adapts, as its target, the current method handle.
 MethodHandle asType(MethodType newType)
          PROVISIONAL API, WORK IN PROGRESS: Produce an adapter method handle which adapts the type of the current method handle to a new type by pairwise argument conversion.
 MethodHandle bindTo(Object x)
          Deprecated. Provisional and unstable; use MethodHandles.insertArguments(java.dyn.MethodHandle, int, java.lang.Object...).
<T> T
invokeExact(Object... arguments)
          PROVISIONAL API, WORK IN PROGRESS: Perform an exact invocation.
<T> T
invokeGeneric()
          PROVISIONAL API, WORK IN PROGRESS: Perform a generic invocation.
<T> T
invokeGeneric(Object a0)
           
<T> T
invokeGeneric(Object a0, Object a1)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3, Object a4)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8)
           
<T> T
invokeGeneric(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9)
           
 Object invokeVarargs(List<?> arguments)
          Equivalent to invokeVarargs(arguments.toArray()).
 Object invokeVarargs(Object[] arguments)
          PROVISIONAL API, WORK IN PROGRESS: Perform a varargs invocation, passing the arguments in the given array to the method handle, as if via invokeGeneric() from a call site which mentions only the type Object, and whose arity is the length of the argument array.
 String toString()
          The string of a direct method handle is the simple name of its target method.
 MethodType type()
          Report the type of this method handle.
 
Methods inherited from class sun.dyn.MethodHandleImpl
accessArrayElement, accessField, addTypeString, bindArgument, bindReceiver, checkSpreadArgument, collectArguments, convertArguments, dropArguments, filterArgument, findMethod, foldArguments, getLookup, getNameString, init, initLookup, initStatics, makeGuardWithCatch, makeGuardWithTest, raiseException, setMethodHandleFriend, spreadArguments, throwException
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

MethodHandle

protected MethodHandle(sun.dyn.Access token,
                       MethodType type)
Class is disabled.

The constructor for MethodHandle may only be called by privileged code. Subclasses may be in other packages, but must possess a token which they obtained from MH with a security check.

Parameters:
token - non-null object which proves access permission
type - type (permanently assigned) of the new method handle
Method Detail

type

public final MethodType type()
Class is disabled.

Report the type of this method handle. Every invocation of this method handle must exactly match this type.

Returns:
the method handle type

toString

public String toString()
Class is disabled.

The string of a direct method handle is the simple name of its target method. The string of an adapter or bound method handle is the string of its target method handle. The string of a Java method handle is the string of its entry point method, unless the Java method handle overrides the toString method.

Overrides:
toString in class Object
Returns:
a string representation of the object.

invokeExact

public final <T> T invokeExact(Object... arguments)
                    throws Throwable
Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Perform an exact invocation. The signature at the call site of invokeExact must exactly match this method handle's type. No conversions are allowed on arguments or return values. This is not yet implemented, pending required compiler and JVM support.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric()
                      throws Throwable
Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Perform a generic invocation. The signature at the call site of invokeExact must have the same arity as this method handle's type. The same conversions are allowed on arguments or return values as are supported by by MethodHandles.convertArguments(java.dyn.MethodHandle, java.dyn.MethodType). If the call site signature exactly matches this method handle's type, the call proceeds as if by invokeExact(java.lang.Object...). This is not fully implemented, pending required compiler and JVM support.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3,
                                 Object a4)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3,
                                 Object a4,
                                 Object a5)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3,
                                 Object a4,
                                 Object a5,
                                 Object a6)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3,
                                 Object a4,
                                 Object a5,
                                 Object a6,
                                 Object a7)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3,
                                 Object a4,
                                 Object a5,
                                 Object a6,
                                 Object a7,
                                 Object a8)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeGeneric

public final <T> T invokeGeneric(Object a0,
                                 Object a1,
                                 Object a2,
                                 Object a3,
                                 Object a4,
                                 Object a5,
                                 Object a6,
                                 Object a7,
                                 Object a8,
                                 Object a9)
                      throws Throwable
Class is disabled.

Throws:
Throwable

invokeVarargs

public final Object invokeVarargs(Object[] arguments)
                           throws Throwable
Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Perform a varargs invocation, passing the arguments in the given array to the method handle, as if via invokeGeneric() from a call site which mentions only the type Object, and whose arity is the length of the argument array.

The length of the arguments array must equal the parameter count of the target's type. The arguments array is spread into separate arguments.

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 equivalent to the following code:

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

Parameters:
arguments - the arguments to pass to the target
Returns:
the result returned by the target
Throws:
Throwable
See Also:
MethodHandles.genericInvoker(java.dyn.MethodType)

invokeVarargs

public final Object invokeVarargs(List<?> arguments)
                           throws Throwable
Class is disabled.

Equivalent to invokeVarargs(arguments.toArray()).

Throws:
Throwable

asType

public final MethodHandle asType(MethodType newType)
Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Produce an adapter method handle which adapts the type of the current 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 this.

This method is equivalent to MethodHandles.convertArguments(java.dyn.MethodHandle, java.dyn.MethodType).

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

asSpreader

public final MethodHandle asSpreader(int keepPosArgs)
Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which adapts, as its target, the current method handle. The type of the adapter will be the same as the type of the target, except that all but the first keepPosArgs parameters of the target's type are replaced by a single array parameter of type Object[]. Thus, if keepPosArgs is zero, the adapter will take all arguments in a single object array.

When called, the adapter replaces a trailing array argument by the array's elements, each as its own argument to the target. (The order of the arguments is preserved.) They are converted pairwise by casting and/or unboxing (as if by MethodHandles.convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)) to the types of the trailing parameters of the target. Finally the target is called. What the target eventually returns is returned unchanged by the adapter.

Before calling the target, the adapter verifies that the array contains exactly enough elements to provide a correct argument count to the target method handle. (The array may also be null when zero elements are required.)

Parameters:
keepPosArgs - the number of leading positional arguments to preserve
Returns:
a new method handle which spreads its final argument, before calling the original method handle
Throws:
IllegalArgumentException - if target does not have at least keepPosArgs parameter types

asCollector

public final MethodHandle asCollector(int spreadArrayArgs)
Deprecated. Provisional and unstable; use MethodHandles.collectArguments(java.dyn.MethodHandle, java.dyn.MethodType).

Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which adapts, as its target, the current method handle. The type of the adapter will be the same as the type of the target, except that a single trailing array parameter of type Object[] is replaced by spreadArrayArgs parameters of type Object.

When called, the adapter replaces its trailing spreadArrayArgs arguments by a single new Object array, whose elements comprise (in order) the replaced arguments. Finally the target is called. What the target eventually returns is returned unchanged by the adapter.

(The array may also be a shared constant when spreadArrayArgs is zero.)

Parameters:
spreadArrayArgs - the number of arguments to spread from the trailing array
Returns:
a new method handle which collects some trailing argument into an array, before calling the original method handle
Throws:
IllegalArgumentException - if the last argument of the target is not Object[]
IllegalArgumentException - if spreadArrayArgs is not a legal array size

bindTo

public final MethodHandle bindTo(Object x)
Deprecated. Provisional and unstable; use MethodHandles.insertArguments(java.dyn.MethodHandle, int, java.lang.Object...).

Class is disabled.

PROVISIONAL API, WORK IN PROGRESS: Produce a method handle which binds the given argument to the current method handle as target. The type of the bound handle will be the same as the type of the target, except that a single leading reference parameter will be omitted.

When called, the bound handle inserts the given value x as a new leading argument to the target. The other arguments are also passed unchanged. What the target eventually returns is returned unchanged by the bound handle.

The reference x must be convertible to the first parameter type of the target.

Parameters:
x - the value to bind to the first argument of the target
Returns:
a new method handle which collects some trailing argument into an array, before calling the original method handle
Throws:
IllegalArgumentException - if the target does not have a leading parameter type that is a reference type
ClassCastException - if x cannot be converted to the leading parameter type of the target