public class LambdaMetafactory extends Object
Bootstrap methods for converting lambda expressions and method references to functional interface objects.
For every lambda expressions or method reference in the source code, there is a target type which is a functional interface. Evaluating a lambda expression produces an object of its target type. The mechanism for evaluating lambda expressions is to invoke an invokedynamic call site, which takes arguments describing the sole method of the functional interface and the implementation method, and returns an object (the lambda object) that implements the target type. Methods of the lambda object invoke the implementation method. For method references, the implementation method is simply the referenced method; for lambda expressions, the implementation method is produced by the compiler based on the body of the lambda expression. The methods in this file are the bootstrap methods for those invokedynamic call sites, called lambda factories, and the bootstrap methods responsible for linking the lambda factories are called lambda meta-factories.
The bootstrap methods in this class take the information about the functional interface, the implementation method, and the static types of the captured lambda arguments, and link a call site which, when invoked, produces the lambda object.
When parameterized types are used, the instantiated type of the functional interface method may be different
from that in the functional interface. For example, consider
interface I<T> { int m(T x); }
if this functional interface type is used in a lambda
I<Byte>; v = ...
, we need both the actual functional interface method which has the signature
(Object)int
and the erased instantiated type of the functional interface method (or simply
instantiated method type), which has signature
(Byte)int
.
The argument list of the implementation method and the argument list of the functional interface method(s) may differ in several ways. The implementation methods may have additional arguments to accommodate arguments captured by the lambda expression; there may also be differences resulting from permitted adaptations of arguments, such as casting, boxing, unboxing, and primitive widening. They may also differ because of var-args, but this is expected to be handled by the compiler.
Invokedynamic call sites have two argument lists: a static argument list and a dynamic argument list. The static argument list lives in the constant pool; the dynamic argument list lives on the operand stack at invocation time. The bootstrap method has access to the entire static argument list (which in this case, contains method handles describing the implementation method and the canonical functional interface method), as well as a method signature describing the number and static types (but not the values) of the dynamic arguments, and the static return type of the invokedynamic site.
The implementation method is described with a method handle. In theory, any method handle could be used. Currently supported are method handles representing invocation of virtual, interface, constructor and static methods.
Assume:
The following signature invariants must hold:
Note that the potentially parameterized implementation return type provides the value for the SAM. Whereas the completely known instantiated return type is adapted to the implementation arguments. Because the instantiated type of the implementation method is not available, the adaptability of return types cannot be checked as precisely at link-time as the arguments can be checked. Thus a loose version of link-time checking is done on return type, while a strict version is applied to arguments.
A type Q is considered adaptable to S as follows:
Q | S | Link-time checks | Capture-time checks |
---|---|---|---|
Primitive | Primitive | Q can be converted to S via a primitive widening conversion | None |
Primitive | Reference | S is a supertype of the Wrapper(Q) | Cast from Wrapper(Q) to S |
Reference | Primitive | strict: Q is a primitive wrapper and Primitive(Q) can be widened to S
loose: If Q is a primitive wrapper, check that Primitive(Q) can be widened to S |
If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types |
Reference | Reference | strict: S is a supertype of Q
loose: none |
Cast from Q to S |
metafactory(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.invoke.MethodType, java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)
) represents the common cases and uses an optimized protocol.
Alternate bootstraps (e.g., altMetafactory(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.Object...)
) exist to support uncommon cases such as serialization
or additional marker superinterfaces.Modifier and Type | Field and Description |
---|---|
static int |
FLAG_BRIDGES
Flag for alternate metafactories indicating the lambda object requires
additional bridge methods
|
static int |
FLAG_MARKERS
Flag for alternate metafactories indicating the lambda object implements
other marker interfaces
besides Serializable
|
static int |
FLAG_SERIALIZABLE
Flag for alternate metafactories indicating the lambda object is
must to be serializable
|
Constructor and Description |
---|
LambdaMetafactory() |
Modifier and Type | Method and Description |
---|---|
static CallSite |
altMetafactory(MethodHandles.Lookup caller,
String invokedName,
MethodType invokedType,
Object... args)
Alternate meta-factory for conversion of lambda expressions or method
references to functional interfaces, which supports serialization and
other uncommon options.
|
static CallSite |
metafactory(MethodHandles.Lookup caller,
String invokedName,
MethodType invokedType,
MethodType samMethodType,
MethodHandle implMethod,
MethodType instantiatedMethodType)
Standard meta-factory for conversion of lambda expressions or method
references to functional interfaces.
|
public static final int FLAG_SERIALIZABLE
public static final int FLAG_MARKERS
public static final int FLAG_BRIDGES
public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType) throws ReflectiveOperationException, LambdaConversionException
caller
- Stacked automatically by VM; represents a lookup context
with the accessibility privileges of the caller.invokedName
- Stacked automatically by VM; the name of the invoked
method as it appears at the call site.
Used as the name of the functional interface method
to which the lambda or method reference is being
converted.invokedType
- Stacked automatically by VM; the signature of the
invoked method, which includes the expected static
type of the returned lambda object, and the static
types of the captured arguments for the lambda.
In the event that the implementation method is an
instance method, the first argument in the invocation
signature will correspond to the receiver.samMethodType
- MethodType of the method in the functional interface
to which the lambda or method reference is being
converted, represented as a MethodType.implMethod
- The implementation method which should be called
(with suitable adaptation of argument types, return
types, and adjustment for captured arguments) when
methods of the resulting functional interface instance
are invoked.instantiatedMethodType
- The signature of the primary functional
interface method after type variables
are substituted with their instantiation
from the capture siteReflectiveOperationException
- if the caller is not able to
reconstruct one of the method handlesLambdaConversionException
- If any of the meta-factory protocol
invariants are violatedpublic static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws ReflectiveOperationException, LambdaConversionException
caller
- Stacked automatically by VM; represents a lookup context
with the accessibility privileges of the caller.invokedName
- Stacked automatically by VM; the name of the invoked
method as it appears at the call site.
Used as the name of the functional interface method
to which the lambda or method reference is being
converted.invokedType
- Stacked automatically by VM; the signature of the
invoked method, which includes the expected static
type of the returned lambda object, and the static
types of the captured arguments for the lambda.
In the event that the implementation method is an
instance method, the first argument in the invocation
signature will correspond to the receiver.args
- flags and optional arguments, as described aboveReflectiveOperationException
- if the caller is not able to
reconstruct one of the method handlesLambdaConversionException
- If any of the meta-factory protocol
invariants are violated 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, 2013, Oracle and/or its affiliates. All rights reserved.
DRAFT internal-0