Spec-Zone .ru
спецификации, руководства, описания, API
|
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
.
While functional interfaces only have a single abstract method from the language perspective (concrete methods in Object are and default methods may be present), at the bytecode level they may actually have multiple methods because of the need for bridge methods. Invoking any of these methods on the lambda object will result in invoking the implementation method.
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.MethodHandle, 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_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,
MethodHandle samMethod,
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 CallSite metaFactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, MethodHandle samMethod, 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.
Currently unused.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.samMethod
- The primary method in the functional interface to which the lambda or method reference is
being converted, represented as a method handle.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
LambdaConversionException
- 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.
Currently unused.invokedType
- Stacked automatically by VM; the signature of the invoked method, which includes thefu
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
- argument to pass, flags, marker interface count, and marker interfaces as described aboveReflectiveOperationException
LambdaConversionException
- If any of the meta-factory protocol invariants are violated
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 ea-b92