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 MethodHandle

java.lang.Object
  extended by sun.dyn.MethodHandleImpl
      extended by java.dyn.MethodHandle
All Implemented Interfaces:
MethodHandleProvider

public abstract class MethodHandle
extends sun.dyn.MethodHandleImpl
implements MethodHandleProvider

A method handle is a typed, directly executable reference to a method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values. (These transformations include conversion, insertion, deletion, substitution. See the methods of this class and of MethodHandles.)

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 matches the method handle's own method 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.methodType(String.class, char.class, char.class);
mh = lookup.findVirtual(String.class, "replace", mt);
// (Ljava/lang/String;CC)Ljava/lang/String;
s = mh.<String>invokeExact("daddy",'d','n');
assert(s.equals("nanny"));
// weakly typed invocation (using MHs.invoke)
s = (String) mh.invokeVarargs("sappy", 'p', 'v');
assert(s.equals("savvy"));
// mt is {Object[] => List}
mt = MethodType.methodType(java.util.List.class, Object[].class);
mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
// mt is {(Object,Object,Object) => Object}
mt = MethodType.genericMethodType(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.invokeExact((Object)1, (Object)2, (Object)3);
assert(x.equals(java.util.Arrays.asList(1,2,3)));
// mt is { => int}
mt = MethodType.methodType(int.class);
mh = lookup.findVirtual(java.util.List.class, "size", mt);
// (Ljava/util/List;)I
i = mh.<int>invokeExact(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.
Signature polymorphic methods in this class appear to be documented as having type parameters for return types and a parameter, but that is merely a documentation convention. These type parameters do not play a role in type-checking method handle invocations.

Like classes and strings, method handles that correspond to accessible fields, methods, and constructors can be represented directly in a class file's constant pool as constants to be loaded by ldc bytecodes. Loading such a constant causes the component classes of its type to be loaded as necessary.

See Also:
MethodType, MethodHandles

Nested Class Summary
Modifier and Type Class and Description
 
Nested classes/interfaces inherited from class sun.dyn.MethodHandleImpl
sun.dyn.MethodHandleImpl.MethodHandleFriend
 
Field Summary
Modifier and Type Field and Description
 
Fields inherited from class sun.dyn.MethodHandleImpl
vmtarget
 
Constructor Summary
Modifier Constructor and Description
protected MethodHandle(sun.dyn.Access token, MethodType type)
          The constructor for MethodHandle may only be called by privileged code.
 
Method Summary
Modifier and Type Method and Description
 MethodHandle asCollector(int spreadArrayArgs)
          Deprecated. Provisional and unstable; use MethodHandles.collectArguments(java.dyn.MethodHandle, java.dyn.MethodType).
 MethodHandle asMethodHandle()
          Implementation of MethodHandleProvider, which returns this.
 MethodHandle asMethodHandle(MethodType type)
          Implementation of MethodHandleProvider, which returns this.asType(type).
 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...).
<R,A> R
invoke(A... args)
          Deprecated. transitional form defined in EDR but removed in PFD
<R,A> R
invokeExact(A... args)
          PROVISIONAL API, WORK IN PROGRESS: Invoke the method handle, allowing any caller signature, but requiring an exact signature match.
<R,A> R
invokeGeneric(A... args)
          PROVISIONAL API, WORK IN PROGRESS: Invoke the method handle, allowing any caller signature, and performing simple conversions for arguments and return types.
 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(A...) 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, getBootstrap, getLookup, getNameString, init, initLookup, initStatics, makeAllocator, makeGuardWithCatch, makeGuardWithTest, raiseException, registerBootstrap, 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)
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()
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()
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 <R,A> R invokeExact(A... args)
                    throws Throwable
PROVISIONAL API, WORK IN PROGRESS: Invoke the method handle, allowing any caller signature, but requiring an exact signature match. 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.

Throws:
Throwable

invoke

public final <R,A> R invoke(A... args)
               throws Throwable
Deprecated. transitional form defined in EDR but removed in PFD

Throws:
Throwable

invokeGeneric

public final <R,A> R invokeGeneric(A... args)
                      throws Throwable
PROVISIONAL API, WORK IN PROGRESS: Invoke the method handle, allowing any caller signature, and performing simple conversions for arguments and return types. The signature at the call site of invokeGeneric must have the same arity as this method handle's type.

If the call site signature exactly matches this method handle's type, the call proceeds as if by invokeExact(A...).

Otherwise, the call proceeds as if this method handle were first adjusted by calling asType(java.dyn.MethodType) to adjust this method handle to the required type, and then the call proceeds as if by invokeExact(A...) on the adjusted method handle.

Throws:
Throwable

invokeVarargs

public final Object invokeVarargs(Object... arguments)
                           throws Throwable
PROVISIONAL API, WORK IN PROGRESS: Perform a varargs invocation, passing the arguments in the given array to the method handle, as if via invokeGeneric(A...) 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.invokeExact(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
Equivalent to invokeVarargs(arguments.toArray()).

Throws:
Throwable

asType

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

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

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

asMethodHandle

public final MethodHandle asMethodHandle()
Implementation of MethodHandleProvider, which returns this.

Specified by:
asMethodHandle in interface MethodHandleProvider

asMethodHandle

public final MethodHandle asMethodHandle(MethodType type)
Implementation of MethodHandleProvider, which returns this.asType(type).

Specified by:
asMethodHandle in interface MethodHandleProvider

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.