Spec-Zone .ru
спецификации, руководства, описания, API
|
|
Java™ Platform Standard Ed. 7 DRAFT ea-b118 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object sun.dyn.MethodHandleImpl java.dyn.MethodHandle
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:
Each of the above calls generates a single invokevirtual instruction with the nameObject 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);
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.
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.
MethodType
,
MethodHandles
Modifier and Type | Class and Description |
---|
Nested classes/interfaces inherited from class sun.dyn.MethodHandleImpl |
---|
sun.dyn.MethodHandleImpl.MethodHandleFriend |
Modifier and Type | Field and Description |
---|
Fields inherited from class sun.dyn.MethodHandleImpl |
---|
vmtarget |
Modifier | Constructor and Description |
---|---|
protected |
MethodHandle(sun.dyn.Access token,
MethodType type)
The constructor for MethodHandle may only be called by privileged code. |
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...) . |
|
|
invoke(A... args)
Deprecated. transitional form defined in EDR but removed in PFD |
|
|
invokeExact(A... args)
PROVISIONAL API, WORK IN PROGRESS: Invoke the method handle, allowing any caller signature, but requiring an exact signature match. |
|
|
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 |
---|
protected MethodHandle(sun.dyn.Access token, MethodType type)
token
- non-null object which proves access permissiontype
- type (permanently assigned) of the new method handleMethod Detail |
---|
public final MethodType type()
public String toString()
toString
in class Object
public final <R,A> R invokeExact(A... args) throws Throwable
invokeExact
must
exactly match this method handle's type
.
No conversions are allowed on arguments or return values.
Throwable
public final <R,A> R invoke(A... args) throws Throwable
Throwable
public final <R,A> R invokeGeneric(A... args) throws Throwable
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.
Throwable
public final Object invokeVarargs(Object... arguments) throws Throwable
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:
byte
to int
This call is equivalent to the following code:
MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true); Object result = invoker.invokeExact(this, arguments);
arguments
- the arguments to pass to the targetThrowable
MethodHandles.genericInvoker(java.dyn.MethodType)
public final Object invokeVarargs(List<?> arguments) throws Throwable
invokeVarargs(arguments.toArray())
.
Throwable
public final MethodHandle asType(MethodType newType)
If the original type and new type are equal, returns this
.
This method is equivalent to MethodHandles.convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
newType
- the expected type of the new method handlethis
after performing
any necessary argument conversions, and arranges for any
necessary return value conversionsIllegalArgumentException
- if the conversion cannot be madeMethodHandles.convertArguments(java.dyn.MethodHandle, java.dyn.MethodType)
public final MethodHandle asSpreader(int keepPosArgs)
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.)
keepPosArgs
- the number of leading positional arguments to preserveIllegalArgumentException
- if target does not have at least
keepPosArgs
parameter typespublic final MethodHandle asCollector(int spreadArrayArgs)
MethodHandles.collectArguments(java.dyn.MethodHandle, java.dyn.MethodType)
.
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.)
spreadArrayArgs
- the number of arguments to spread from the trailing arrayIllegalArgumentException
- if the last argument of the target
is not Object[]
IllegalArgumentException
- if spreadArrayArgs
is not
a legal array sizepublic final MethodHandle bindTo(Object x)
MethodHandles.insertArguments(java.dyn.MethodHandle, int, java.lang.Object...)
.
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.
x
- the value to bind to the first argument of the targetIllegalArgumentException
- if the target does not have a
leading parameter type that is a reference typeClassCastException
- if x
cannot be converted
to the leading parameter type of the targetpublic final MethodHandle asMethodHandle()
MethodHandleProvider
, which returns this
.
asMethodHandle
in interface MethodHandleProvider
public final MethodHandle asMethodHandle(MethodType type)
MethodHandleProvider
, which returns this.asType(type)
.
asMethodHandle
in interface MethodHandleProvider
|
Java™ Platform Standard Ed. 7 DRAFT ea-b118 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Copyright © 1993, 2010, Oracle Corporation. All rights reserved.