java.lang.invoke
package provides low-level primitives for interacting
with the Java Virtual Machine.
As described in the Java Virtual Machine Specification, certain types in this package are given special treatment by the virtual machine:
MethodHandle
and
VarHandle
contain
signature polymorphic methods
which can be linked regardless of their type descriptor.
Normally, method linkage requires exact matching of type descriptors.
MethodHandle
and
MethodType
.
invokedynamic
instruction makes use of bootstrap MethodHandle
constants to dynamically resolve CallSite
objects for custom method invocation
behavior.
ldc
instruction makes use of bootstrap MethodHandle
constants
to dynamically resolve custom constant values.
invokedynamic
instruction is originally in an unlinked state.
In this state, there is no target method for the instruction to invoke.
Before the JVM can execute an invokedynamic
instruction,
the instruction must first be linked.
Linking is accomplished by calling a bootstrap method
which is given the static information content of the call,
and which must produce a java.
that gives the behavior of the invocation.
Each invokedynamic
instruction statically specifies its own
bootstrap method as a constant pool reference.
The constant pool reference also specifies the invocation's name and method type descriptor,
just like invokestatic
and the other invoke instructions.
CONSTANT_Dynamic
,
equipped with bootstrap methods which perform their resolution.
Such a dynamic constant is originally in an unresolved state.
Before the JVM can use a dynamically-computed constant, it must first be resolved.
Dynamically-computed constant resolution is accomplished by calling a bootstrap method
which is given the static information content of the constant,
and which must produce a value of the constant's statically declared type.
Each dynamically-computed constant statically specifies its own
bootstrap method as a constant pool reference.
The constant pool reference also specifies the constant's name and field type descriptor,
just like getstatic
and the other field reference instructions.
(Roughly speaking, a dynamically-computed constant is to a dynamically-computed call site
as a CONSTANT_Fieldref
is to a CONSTANT_Methodref
.)
CONSTANT_MethodHandle
Class
or MethodType
derived from
type component of the CONSTANT_NameAndType
descriptor
The bootstrap method is then invoked, as if by
MethodHandle.
,
with the following arguments:
MethodHandles.Lookup
, which is a lookup object on the caller class
in which dynamically-computed constant or call site occursString
, the name mentioned in the CONSTANT_NameAndType
MethodType
or Class
, the resolved type descriptor of the CONSTANT_NameAndType
Class
, the resolved type descriptor of the constant, if it is a dynamic constant
For a dynamically-computed call site, the returned result must be a non-null reference to a
CallSite
.
The type of the call site's target must be exactly equal to the type
derived from the invocation's type descriptor and passed to
the bootstrap method. If these conditions are not met, a BootstrapMethodError
is thrown.
On success the call site then becomes permanently linked to the invokedynamic
instruction.
For a dynamically-computed constant, the first parameter of the bootstrap
method must be assignable to MethodHandles.Lookup
. If this condition
is not met, a BootstrapMethodError
is thrown.
On success the result of the bootstrap method is cached as the resolved
constant value.
If an exception, E
say, occurs during execution of the bootstrap method, then
resolution fails and terminates abnormally. E
is rethrown if the type of
E
is Error
or a subclass, otherwise a
BootstrapMethodError
that wraps E
is thrown.
If this happens, the same error will be thrown for all
subsequent attempts to execute the invokedynamic
instruction or load the
dynamically-computed constant.
invokedynamic
instruction is linked just before its first execution.
A dynamically-computed constant is resolved just before the first time it is used
(by pushing it on the stack or linking it as a bootstrap method parameter).
The bootstrap method call implementing the linkage occurs within
a thread that is attempting a first execution or first use.
If there are several such threads, the bootstrap method may be
invoked in several threads concurrently.
Therefore, bootstrap methods which access global application
data must take the usual precautions against race conditions.
In any case, every invokedynamic
instruction is either
unlinked or linked to a unique CallSite
object.
In an application which requires invokedynamic
instructions with individually
mutable behaviors, their bootstrap methods should produce distinct
CallSite
objects, one for each linkage request.
Alternatively, an application can link a single CallSite
object
to several invokedynamic
instructions, in which case
a change to the target method will become visible at each of
the instructions.
If several threads simultaneously execute a bootstrap method for a single dynamically-computed call site or constant, the JVM must choose one bootstrap method result and install it visibly to all threads. Any other bootstrap method calls are allowed to complete, but their results are ignored.
Discussion:
These rules do not enable the JVM to share call sites,
or to issue “causeless” bootstrap method calls.
Every invokedynamic
instruction transitions at most once from unlinked to linked,
just before its first invocation.
There is no way to undo the effect of a completed bootstrap method call.
MethodHandles.Lookup
, String
, MethodType
, and the types
of any static arguments; the return type is CallSite
.
For a dynamically-computed constant, the bootstrap method is invoked with parameter types
MethodHandles.Lookup
, String
, Class
, and the types of any
static arguments; the return type is the type represented by the Class
.
Because MethodHandle.
allows for
adaptations between the invoked method type and the bootstrap method handle's method type,
there is flexibility in the declaration of the bootstrap method.
For a dynamically-computed constant the first parameter type of the bootstrap method handle
must be assignable to MethodHandles.Lookup
, other than that constraint the same degree
of flexibility applies to bootstrap methods of dynamically-computed call sites and
dynamically-computed constants.
Note
this constraint allows for the future possibility where the bootstrap method is invoked with just the parameter types of static arguments, thereby supporting a wider range of methods compatible with the static arguments (such as methods that don't declare or require the lookup, name, and type meta-data parameters).
For example, for dynamically-computed call site, the first argument
could be Object
instead of MethodHandles.Lookup
, and the return type
could also be Object
instead of CallSite
.
(Note that the types and number of the stacked arguments limit
the legal kinds of bootstrap methods to appropriately typed
static methods and constructors.)
If a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
If the bootstrap method is a variable arity method (its modifier bit 0x0080
is set),
then some or all of the arguments specified here may be collected into a trailing array parameter.
(This is not a special rule, but rather a useful consequence of the interaction
between CONSTANT_MethodHandle
constants, the modifier bit for variable arity methods,
and the asVarargsCollector
transformation.)
Given these rules, here are examples of legal bootstrap method declarations for
dynamically-computed call sites, given various numbers N
of extra arguments.
The first row (marked *
) will work for any number of extra arguments.
N | Sample bootstrap method |
---|---|
* |
|
0 |
|
1 |
CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg) |
2 |
|
String
and Integer
(or int
), respectively.
The second-to-last example assumes that all extra arguments are of type
String
.
The other examples work with all types of extra arguments. Note that all
the examples except the second and third also work with dynamically-computed
constants if the return type is changed to be compatible with the
constant's declared type (such as Object
, which is always compatible).
Since dynamically-computed constants can be provided as static arguments to bootstrap
methods, there are no limitations on the types of bootstrap arguments.
However, arguments of type boolean
, byte
, short
, or char
cannot be directly supplied by CONSTANT_Integer
constant pool entries, since the asType
conversions do
not perform the necessary narrowing primitive conversions.
In the above examples, the return type is always CallSite
,
but that is not a necessary feature of bootstrap methods.
In the case of a dynamically-computed call site, the only requirement is that
the return type of the bootstrap method must be convertible
(using the asType
conversions) to CallSite
, which
means the bootstrap method return type might be Object
or
ConstantCallSite
.
In the case of a dynamically-resolved constant, the return type of the bootstrap
method must be convertible to the type of the constant, as
represented by its field type descriptor. For example, if the
dynamic constant has a field type descriptor of "C"
(char
) then the bootstrap method return type could be
Object
, Character
, or char
, but not
int
or Integer
.
Modifier and Type | Interface and Description |
---|---|
pack-priv interface | BootstrapCallInfo<T>
An interface providing full static information about a particular call to a bootstrap method of a dynamic call site or dynamic constant. |
pack-priv interface | ConstantGroup
An ordered sequence of constants, some of which may not yet be present. |
public interface | MethodHandleInfo
A symbolic reference obtained by cracking a direct method handle into its constituent symbolic parts. |
public interface | TypeDescriptor
An entity that has a type descriptor. |
Modifier and Type | Annotation and Description |
---|---|
pack-priv @interface | InjectedProfile
Internal marker for some methods in the JSR 292 implementation. |
Modifier and Type | Class and Description |
---|---|
pack-priv abstract class | AbstractConstantGroup
Utility class for implementing ConstantGroup. |
pack-priv abstract class | AbstractValidatingLambdaMetafactory
Abstract implementation of a lambda metafactory which provides parameter unrolling and input validation. |
pack-priv class | |
pack-priv abstract class | BoundMethodHandle
The flavor of method handle which emulates an invoke instruction on a predetermined argument. |
public abstract class | CallSite
A |
pack-priv abstract class | ClassSpecializer<
top class under which species classes are created. T, key which identifies individual specializations. K, species data type. S extends ClassSpecializerClass specialization code. |
public class | ConstantBootstraps
Bootstrap methods for dynamically-computed constants. |
public class | ConstantCallSite
A |
pack-priv abstract class | DelegatingMethodHandle
A method handle whose invocation behavior is determined by a target. |
pack-priv class | DirectMethodHandle
The flavor of method handle which implements a constant reference to a class member. |
pack-priv class | GenerateJLIClassesHelper
Helper class to assist the GenerateJLIClassesPlugin to get access to generate classes ahead of time. |
pack-priv class | IndirectVarHandle
An indirect var handle can be thought of as an aggregate of the method handles implementing its supported access modes. |
pack-priv class | |
pack-priv class | InnerClassLambdaMetafactory
Lambda metafactory implementation which dynamically creates an inner-class-like class per lambda callsite. |
pack-priv class | InvokeDynamic
This is a place-holder class. |
pack-priv class | InvokerBytecodeGenerator
Code generation backend for LambdaForm. |
pack-priv class | Invokers
Construction and caching of often-used invokers. |
public class | LambdaConversionException
LambdaConversionException |
pack-priv class | LambdaForm
The symbolic, non-executable form of a method handle's invocation semantics. |
pack-priv class | LambdaFormBuffer
Working storage for an LF that is being transformed. |
pack-priv class | LambdaFormEditor
Transforms on LFs. |
public class | LambdaMetafactory
Methods to facilitate the creation of simple "function objects" that
implement one or more interfaces by delegation to a provided |
pack-priv class | |
pack-priv class | LazyInitializingVarHandle
A lazy initializing var handle. |
pack-priv class | MemberName
A |
public abstract class | MethodHandle
A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values. |
pack-priv abstract class | MethodHandleImpl
Trusted implementation code for MethodHandle. |
pack-priv class | MethodHandleNatives
The JVM interface for the method handles package is all here. |
public class | MethodHandleProxies
This class consists exclusively of static methods that help adapt method handles to other JVM types, such as interfaces. |
public class | MethodHandles
This class consists exclusively of static methods that operate on or return method handles. |
pack-priv class | MethodHandleStatics
This class consists exclusively of static names internal to the method handle implementation. |
public class | MethodType
A method type represents the arguments and return type accepted and returned by a method handle, or the arguments and return type passed and expected by a method handle caller. |
pack-priv class | MethodTypeForm
Shared information for a group of method types, which differ only by reference types, and therefore share a common erasure and wrapping. |
public class | MutableCallSite
A |
pack-priv class | NativeMethodHandle
This class models a method handle to a native function. |
pack-priv class | |
public class | SerializedLambda
Serialized form of a lambda expression. |
pack-priv class | SimpleMethodHandle
A method handle whose behavior is determined only by its LambdaForm. |
public class | StringConcatException
StringConcatException is thrown by |
public class | StringConcatFactory
Methods to facilitate the creation of String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments. |
public class | SwitchPoint
A |
pack-priv class | |
pack-priv class | VarForm
A var handle form containing a set of member name, one for each operation. |
public abstract class | VarHandle
A VarHandle is a dynamically strongly typed reference to a variable, or to a parametrically-defined family of variables, including static fields, non-static fields, array elements, or components of an off-heap data structure. |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv abstract class | VarHandleByteArrayBase
The base class for generated byte array and byte buffer view implementations |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv class | |
pack-priv abstract class | VarHandleSegmentViewBase
Base class for memory segment var handle view implementations. |
pack-priv class | |
public class | VolatileCallSite
A |
public class | WrongMethodTypeException
Thrown to indicate that code has attempted to call a method handle via the wrong method type. |