Adding necessary fake classes to allow Javac to compile lamda expressions against our emulation library.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/CallSite.java Sun Sep 14 19:27:44 2014 +0200
1.3 @@ -0,0 +1,191 @@
1.4 +/*
1.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang.invoke;
1.30 +
1.31 +/**
1.32 + * A {@code CallSite} is a holder for a variable {@link MethodHandle},
1.33 + * which is called its {@code target}.
1.34 + * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
1.35 + * all calls to the site's current target.
1.36 + * A {@code CallSite} may be associated with several {@code invokedynamic}
1.37 + * instructions, or it may be "free floating", associated with none.
1.38 + * In any case, it may be invoked through an associated method handle
1.39 + * called its {@linkplain #dynamicInvoker dynamic invoker}.
1.40 + * <p>
1.41 + * {@code CallSite} is an abstract class which does not allow
1.42 + * direct subclassing by users. It has three immediate,
1.43 + * concrete subclasses that may be either instantiated or subclassed.
1.44 + * <ul>
1.45 + * <li>If a mutable target is not required, an {@code invokedynamic} instruction
1.46 + * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
1.47 + * <li>If a mutable target is required which has volatile variable semantics,
1.48 + * because updates to the target must be immediately and reliably witnessed by other threads,
1.49 + * a {@linkplain VolatileCallSite volatile call site} may be used.
1.50 + * <li>Otherwise, if a mutable target is required,
1.51 + * a {@linkplain MutableCallSite mutable call site} may be used.
1.52 + * </ul>
1.53 + * <p>
1.54 + * A non-constant call site may be <em>relinked</em> by changing its target.
1.55 + * The new target must have the same {@linkplain MethodHandle#type() type}
1.56 + * as the previous target.
1.57 + * Thus, though a call site can be relinked to a series of
1.58 + * successive targets, it cannot change its type.
1.59 + * <p>
1.60 + * Here is a sample use of call sites and bootstrap methods which links every
1.61 + * dynamic call site to print its arguments:
1.62 +<blockquote><pre>{@code
1.63 +static void test() throws Throwable {
1.64 + // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
1.65 + InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
1.66 +}
1.67 +private static void printArgs(Object... args) {
1.68 + System.out.println(java.util.Arrays.deepToString(args));
1.69 +}
1.70 +private static final MethodHandle printArgs;
1.71 +static {
1.72 + MethodHandles.Lookup lookup = MethodHandles.lookup();
1.73 + Class thisClass = lookup.lookupClass(); // (who am I?)
1.74 + printArgs = lookup.findStatic(thisClass,
1.75 + "printArgs", MethodType.methodType(void.class, Object[].class));
1.76 +}
1.77 +private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
1.78 + // ignore caller and name, but match the type:
1.79 + return new ConstantCallSite(printArgs.asType(type));
1.80 +}
1.81 +}</pre></blockquote>
1.82 + * @author John Rose, JSR 292 EG
1.83 + */
1.84 +abstract
1.85 +public class CallSite {
1.86 + // The actual payload of this call site:
1.87 + /*package-private*/
1.88 + MethodHandle target; // Note: This field is known to the JVM. Do not change.
1.89 +
1.90 + /**
1.91 + * Make a blank call site object with the given method type.
1.92 + * An initial target method is supplied which will throw
1.93 + * an {@link IllegalStateException} if called.
1.94 + * <p>
1.95 + * Before this {@code CallSite} object is returned from a bootstrap method,
1.96 + * it is usually provided with a more useful target method,
1.97 + * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
1.98 + * @throws NullPointerException if the proposed type is null
1.99 + */
1.100 + /*package-private*/
1.101 + CallSite(MethodType type) {
1.102 + throw new IllegalStateException();
1.103 + }
1.104 +
1.105 + /**
1.106 + * Make a call site object equipped with an initial target method handle.
1.107 + * @param target the method handle which will be the initial target of the call site
1.108 + * @throws NullPointerException if the proposed target is null
1.109 + */
1.110 + /*package-private*/
1.111 + CallSite(MethodHandle target) {
1.112 + target.type(); // null check
1.113 + this.target = target;
1.114 + }
1.115 +
1.116 + /**
1.117 + * Make a call site object equipped with an initial target method handle.
1.118 + * @param targetType the desired type of the call site
1.119 + * @param createTargetHook a hook which will bind the call site to the target method handle
1.120 + * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
1.121 + * or if the target returned by the hook is not of the given {@code targetType}
1.122 + * @throws NullPointerException if the hook returns a null value
1.123 + * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
1.124 + * @throws Throwable anything else thrown by the hook function
1.125 + */
1.126 + /*package-private*/
1.127 + CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
1.128 + throw new IllegalStateException();
1.129 + }
1.130 +
1.131 + /**
1.132 + * Returns the type of this call site's target.
1.133 + * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
1.134 + * The {@code setTarget} method enforces this invariant by refusing any new target that does
1.135 + * not have the previous target's type.
1.136 + * @return the type of the current target, which is also the type of any future target
1.137 + */
1.138 + public MethodType type() {
1.139 + // warning: do not call getTarget here, because CCS.getTarget can throw IllegalStateException
1.140 + return target.type();
1.141 + }
1.142 +
1.143 + /**
1.144 + * Returns the target method of the call site, according to the
1.145 + * behavior defined by this call site's specific class.
1.146 + * The immediate subclasses of {@code CallSite} document the
1.147 + * class-specific behaviors of this method.
1.148 + *
1.149 + * @return the current linkage state of the call site, its target method handle
1.150 + * @see ConstantCallSite
1.151 + * @see VolatileCallSite
1.152 + * @see #setTarget
1.153 + * @see ConstantCallSite#getTarget
1.154 + * @see MutableCallSite#getTarget
1.155 + * @see VolatileCallSite#getTarget
1.156 + */
1.157 + public abstract MethodHandle getTarget();
1.158 +
1.159 + /**
1.160 + * Updates the target method of this call site, according to the
1.161 + * behavior defined by this call site's specific class.
1.162 + * The immediate subclasses of {@code CallSite} document the
1.163 + * class-specific behaviors of this method.
1.164 + * <p>
1.165 + * The type of the new target must be {@linkplain MethodType#equals equal to}
1.166 + * the type of the old target.
1.167 + *
1.168 + * @param newTarget the new target
1.169 + * @throws NullPointerException if the proposed new target is null
1.170 + * @throws WrongMethodTypeException if the proposed new target
1.171 + * has a method type that differs from the previous target
1.172 + * @see CallSite#getTarget
1.173 + * @see ConstantCallSite#setTarget
1.174 + * @see MutableCallSite#setTarget
1.175 + * @see VolatileCallSite#setTarget
1.176 + */
1.177 + public abstract void setTarget(MethodHandle newTarget);
1.178 +
1.179 + /**
1.180 + * Produces a method handle equivalent to an invokedynamic instruction
1.181 + * which has been linked to this call site.
1.182 + * <p>
1.183 + * This method is equivalent to the following code:
1.184 + * <blockquote><pre>{@code
1.185 + * MethodHandle getTarget, invoker, result;
1.186 + * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
1.187 + * invoker = MethodHandles.exactInvoker(this.type());
1.188 + * result = MethodHandles.foldArguments(invoker, getTarget)
1.189 + * }</pre></blockquote>
1.190 + *
1.191 + * @return a method handle which always invokes this call site's current target
1.192 + */
1.193 + public abstract MethodHandle dynamicInvoker();
1.194 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/LambdaMetafactory.java Sun Sep 14 19:27:44 2014 +0200
2.3 @@ -0,0 +1,426 @@
2.4 +/*
2.5 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.7 + *
2.8 + * This code is free software; you can redistribute it and/or modify it
2.9 + * under the terms of the GNU General Public License version 2 only, as
2.10 + * published by the Free Software Foundation. Oracle designates this
2.11 + * particular file as subject to the "Classpath" exception as provided
2.12 + * by Oracle in the LICENSE file that accompanied this code.
2.13 + *
2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2.17 + * version 2 for more details (a copy is included in the LICENSE file that
2.18 + * accompanied this code).
2.19 + *
2.20 + * You should have received a copy of the GNU General Public License version
2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2.23 + *
2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2.25 + * or visit www.oracle.com if you need additional information or have any
2.26 + * questions.
2.27 + */
2.28 +
2.29 +package java.lang.invoke;
2.30 +
2.31 +import java.io.Serializable;
2.32 +import java.util.Arrays;
2.33 +
2.34 +/**
2.35 + * <p>Methods to facilitate the creation of simple "function objects" that
2.36 + * implement one or more interfaces by delegation to a provided {@link MethodHandle},
2.37 + * possibly after type adaptation and partial evaluation of arguments. These
2.38 + * methods are typically used as <em>bootstrap methods</em> for {@code invokedynamic}
2.39 + * call sites, to support the <em>lambda expression</em> and <em>method
2.40 + * reference expression</em> features of the Java Programming Language.
2.41 + *
2.42 + * <p>Indirect access to the behavior specified by the provided {@code MethodHandle}
2.43 + * proceeds in order through three phases:
2.44 + * <ul>
2.45 + * <li><em>Linkage</em> occurs when the methods in this class are invoked.
2.46 + * They take as arguments an interface to be implemented (typically a
2.47 + * <em>functional interface</em>, one with a single abstract method), a
2.48 + * name and signature of a method from that interface to be implemented, a
2.49 + * method handle describing the desired implementation behavior
2.50 + * for that method, and possibly other additional metadata, and produce a
2.51 + * {@link CallSite} whose target can be used to create suitable function
2.52 + * objects. Linkage may involve dynamically loading a new class that
2.53 + * implements the target interface. The {@code CallSite} can be considered a
2.54 + * "factory" for function objects and so these linkage methods are referred
2.55 + * to as "metafactories".</li>
2.56 + *
2.57 + * <li><em>Capture</em> occurs when the {@code CallSite}'s target is
2.58 + * invoked, typically through an {@code invokedynamic} call site,
2.59 + * producing a function object. This may occur many times for
2.60 + * a single factory {@code CallSite}. Capture may involve allocation of a
2.61 + * new function object, or may return an existing function object. The
2.62 + * behavior {@code MethodHandle} may have additional parameters beyond those
2.63 + * of the specified interface method; these are referred to as <em>captured
2.64 + * parameters</em>, which must be provided as arguments to the
2.65 + * {@code CallSite} target, and which may be early-bound to the behavior
2.66 + * {@code MethodHandle}. The number of captured parameters and their types
2.67 + * are determined during linkage.</li>
2.68 + *
2.69 + * <li><em>Invocation</em> occurs when an implemented interface method
2.70 + * is invoked on a function object. This may occur many times for a single
2.71 + * function object. The method referenced by the behavior {@code MethodHandle}
2.72 + * is invoked with the captured arguments and any additional arguments
2.73 + * provided on invocation, as if by {@link MethodHandle#invoke(Object...)}.</li>
2.74 + * </ul>
2.75 + *
2.76 + * <p>It is sometimes useful to restrict the set of inputs or results permitted
2.77 + * at invocation. For example, when the generic interface {@code Predicate<T>}
2.78 + * is parameterized as {@code Predicate<String>}, the input must be a
2.79 + * {@code String}, even though the method to implement allows any {@code Object}.
2.80 + * At linkage time, an additional {@link MethodType} parameter describes the
2.81 + * "instantiated" method type; on invocation, the arguments and eventual result
2.82 + * are checked against this {@code MethodType}.
2.83 + *
2.84 + * <p>This class provides two forms of linkage methods: a standard version
2.85 + * ({@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)})
2.86 + * using an optimized protocol, and an alternate version
2.87 + * {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}).
2.88 + * The alternate version is a generalization of the standard version, providing
2.89 + * additional control over the behavior of the generated function objects via
2.90 + * flags and additional arguments. The alternate version adds the ability to
2.91 + * manage the following attributes of function objects:
2.92 + *
2.93 + * <ul>
2.94 + * <li><em>Bridging.</em> It is sometimes useful to implement multiple
2.95 + * variations of the method signature, involving argument or return type
2.96 + * adaptation. This occurs when multiple distinct VM signatures for a method
2.97 + * are logically considered to be the same method by the language. The
2.98 + * flag {@code FLAG_BRIDGES} indicates that a list of additional
2.99 + * {@code MethodType}s will be provided, each of which will be implemented
2.100 + * by the resulting function object. These methods will share the same
2.101 + * name and instantiated type.</li>
2.102 + *
2.103 + * <li><em>Multiple interfaces.</em> If needed, more than one interface
2.104 + * can be implemented by the function object. (These additional interfaces
2.105 + * are typically marker interfaces with no methods.) The flag {@code FLAG_MARKERS}
2.106 + * indicates that a list of additional interfaces will be provided, each of
2.107 + * which should be implemented by the resulting function object.</li>
2.108 + *
2.109 + * <li><em>Serializability.</em> The generated function objects do not
2.110 + * generally support serialization. If desired, {@code FLAG_SERIALIZABLE}
2.111 + * can be used to indicate that the function objects should be serializable.
2.112 + * Serializable function objects will use, as their serialized form,
2.113 + * instances of the class {@code SerializedLambda}, which requires additional
2.114 + * assistance from the capturing class (the class described by the
2.115 + * {@link MethodHandles.Lookup} parameter {@code caller}); see
2.116 + * {@link SerializedLambda} for details.</li>
2.117 + * </ul>
2.118 + *
2.119 + * <p>Assume the linkage arguments are as follows:
2.120 + * <ul>
2.121 + * <li>{@code invokedType} (describing the {@code CallSite} signature) has
2.122 + * K parameters of types (D1..Dk) and return type Rd;</li>
2.123 + * <li>{@code samMethodType} (describing the implemented method type) has N
2.124 + * parameters, of types (U1..Un) and return type Ru;</li>
2.125 + * <li>{@code implMethod} (the {@code MethodHandle} providing the
2.126 + * implementation has M parameters, of types (A1..Am) and return type Ra
2.127 + * (if the method describes an instance method, the method type of this
2.128 + * method handle already includes an extra first argument corresponding to
2.129 + * the receiver);</li>
2.130 + * <li>{@code instantiatedMethodType} (allowing restrictions on invocation)
2.131 + * has N parameters, of types (T1..Tn) and return type Rt.</li>
2.132 + * </ul>
2.133 + *
2.134 + * <p>Then the following linkage invariants must hold:
2.135 + * <ul>
2.136 + * <li>Rd is an interface</li>
2.137 + * <li>{@code implMethod} is a <em>direct method handle</em></li>
2.138 + * <li>{@code samMethodType} and {@code instantiatedMethodType} have the same
2.139 + * arity N, and for i=1..N, Ti and Ui are the same type, or Ti and Ui are
2.140 + * both reference types and Ti is a subtype of Ui</li>
2.141 + * <li>Either Rt and Ru are the same type, or both are reference types and
2.142 + * Rt is a subtype of Ru</li>
2.143 + * <li>K + N = M</li>
2.144 + * <li>For i=1..K, Di = Ai</li>
2.145 + * <li>For i=1..N, Ti is adaptable to Aj, where j=i+k</li>
2.146 + * <li>The return type Rt is void, or the return type Ra is not void and is
2.147 + * adaptable to Rt</li>
2.148 + * </ul>
2.149 + *
2.150 + * <p>Further, at capture time, if {@code implMethod} corresponds to an instance
2.151 + * method, and there are any capture arguments ({@code K > 0}), then the first
2.152 + * capture argument (corresponding to the receiver) must be non-null.
2.153 + *
2.154 + * <p>A type Q is considered adaptable to S as follows:
2.155 + * <table summary="adaptable types">
2.156 + * <tr><th>Q</th><th>S</th><th>Link-time checks</th><th>Invocation-time checks</th></tr>
2.157 + * <tr>
2.158 + * <td>Primitive</td><td>Primitive</td>
2.159 + * <td>Q can be converted to S via a primitive widening conversion</td>
2.160 + * <td>None</td>
2.161 + * </tr>
2.162 + * <tr>
2.163 + * <td>Primitive</td><td>Reference</td>
2.164 + * <td>S is a supertype of the Wrapper(Q)</td>
2.165 + * <td>Cast from Wrapper(Q) to S</td>
2.166 + * </tr>
2.167 + * <tr>
2.168 + * <td>Reference</td><td>Primitive</td>
2.169 + * <td>for parameter types: Q is a primitive wrapper and Primitive(Q)
2.170 + * can be widened to S
2.171 + * <br>for return types: If Q is a primitive wrapper, check that
2.172 + * Primitive(Q) can be widened to S</td>
2.173 + * <td>If Q is not a primitive wrapper, cast Q to the base Wrapper(S);
2.174 + * for example Number for numeric types</td>
2.175 + * </tr>
2.176 + * <tr>
2.177 + * <td>Reference</td><td>Reference</td>
2.178 + * <td>for parameter types: S is a supertype of Q
2.179 + * <br>for return types: none</td>
2.180 + * <td>Cast from Q to S</td>
2.181 + * </tr>
2.182 + * </table>
2.183 + *
2.184 + * @apiNote These linkage methods are designed to support the evaluation
2.185 + * of <em>lambda expressions</em> and <em>method references</em> in the Java
2.186 + * Language. For every lambda expressions or method reference in the source code,
2.187 + * there is a target type which is a functional interface. Evaluating a lambda
2.188 + * expression produces an object of its target type. The recommended mechanism
2.189 + * for evaluating lambda expressions is to desugar the lambda body to a method,
2.190 + * invoke an invokedynamic call site whose static argument list describes the
2.191 + * sole method of the functional interface and the desugared implementation
2.192 + * method, and returns an object (the lambda object) that implements the target
2.193 + * type. (For method references, the implementation method is simply the
2.194 + * referenced method; no desugaring is needed.)
2.195 + *
2.196 + * <p>The argument list of the implementation method and the argument list of
2.197 + * the interface method(s) may differ in several ways. The implementation
2.198 + * methods may have additional arguments to accommodate arguments captured by
2.199 + * the lambda expression; there may also be differences resulting from permitted
2.200 + * adaptations of arguments, such as casting, boxing, unboxing, and primitive
2.201 + * widening. (Varargs adaptations are not handled by the metafactories; these are
2.202 + * expected to be handled by the caller.)
2.203 + *
2.204 + * <p>Invokedynamic call sites have two argument lists: a static argument list
2.205 + * and a dynamic argument list. The static argument list is stored in the
2.206 + * constant pool; the dynamic argument is pushed on the operand stack at capture
2.207 + * time. The bootstrap method has access to the entire static argument list
2.208 + * (which in this case, includes information describing the implementation method,
2.209 + * the target interface, and the target interface method(s)), as well as a
2.210 + * method signature describing the number and static types (but not the values)
2.211 + * of the dynamic arguments and the static return type of the invokedynamic site.
2.212 + *
2.213 + * @implNote The implementation method is described with a method handle. In
2.214 + * theory, any method handle could be used. Currently supported are direct method
2.215 + * handles representing invocation of virtual, interface, constructor and static
2.216 + * methods.
2.217 + */
2.218 +public class LambdaMetafactory {
2.219 +
2.220 + /** Flag for alternate metafactories indicating the lambda object
2.221 + * must be serializable */
2.222 + public static final int FLAG_SERIALIZABLE = 1 << 0;
2.223 +
2.224 + /**
2.225 + * Flag for alternate metafactories indicating the lambda object implements
2.226 + * other marker interfaces
2.227 + * besides Serializable
2.228 + */
2.229 + public static final int FLAG_MARKERS = 1 << 1;
2.230 +
2.231 + /**
2.232 + * Flag for alternate metafactories indicating the lambda object requires
2.233 + * additional bridge methods
2.234 + */
2.235 + public static final int FLAG_BRIDGES = 1 << 2;
2.236 +
2.237 + private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
2.238 + private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
2.239 +
2.240 + /**
2.241 + * Facilitates the creation of simple "function objects" that implement one
2.242 + * or more interfaces by delegation to a provided {@link MethodHandle},
2.243 + * after appropriate type adaptation and partial evaluation of arguments.
2.244 + * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
2.245 + * call sites, to support the <em>lambda expression</em> and <em>method
2.246 + * reference expression</em> features of the Java Programming Language.
2.247 + *
2.248 + * <p>This is the standard, streamlined metafactory; additional flexibility
2.249 + * is provided by {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}.
2.250 + * A general description of the behavior of this method is provided
2.251 + * {@link LambdaMetafactory above}.
2.252 + *
2.253 + * <p>When the target of the {@code CallSite} returned from this method is
2.254 + * invoked, the resulting function objects are instances of a class which
2.255 + * implements the interface named by the return type of {@code invokedType},
2.256 + * declares a method with the name given by {@code invokedName} and the
2.257 + * signature given by {@code samMethodType}. It may also override additional
2.258 + * methods from {@code Object}.
2.259 + *
2.260 + * @param caller Represents a lookup context with the accessibility
2.261 + * privileges of the caller. When used with {@code invokedynamic},
2.262 + * this is stacked automatically by the VM.
2.263 + * @param invokedName The name of the method to implement. When used with
2.264 + * {@code invokedynamic}, this is provided by the
2.265 + * {@code NameAndType} of the {@code InvokeDynamic}
2.266 + * structure and is stacked automatically by the VM.
2.267 + * @param invokedType The expected signature of the {@code CallSite}. The
2.268 + * parameter types represent the types of capture variables;
2.269 + * the return type is the interface to implement. When
2.270 + * used with {@code invokedynamic}, this is provided by
2.271 + * the {@code NameAndType} of the {@code InvokeDynamic}
2.272 + * structure and is stacked automatically by the VM.
2.273 + * In the event that the implementation method is an
2.274 + * instance method and this signature has any parameters,
2.275 + * the first parameter in the invocation signature must
2.276 + * correspond to the receiver.
2.277 + * @param samMethodType Signature and return type of method to be implemented
2.278 + * by the function object.
2.279 + * @param implMethod A direct method handle describing the implementation
2.280 + * method which should be called (with suitable adaptation
2.281 + * of argument types, return types, and with captured
2.282 + * arguments prepended to the invocation arguments) at
2.283 + * invocation time.
2.284 + * @param instantiatedMethodType The signature and return type that should
2.285 + * be enforced dynamically at invocation time.
2.286 + * This may be the same as {@code samMethodType},
2.287 + * or may be a specialization of it.
2.288 + * @return a CallSite whose target can be used to perform capture, generating
2.289 + * instances of the interface named by {@code invokedType}
2.290 + * @throws LambdaConversionException If any of the linkage invariants
2.291 + * described {@link LambdaMetafactory above}
2.292 + * are violated
2.293 + */
2.294 + public static CallSite metafactory(MethodHandles.Lookup caller,
2.295 + String invokedName,
2.296 + MethodType invokedType,
2.297 + MethodType samMethodType,
2.298 + MethodHandle implMethod,
2.299 + MethodType instantiatedMethodType)
2.300 + {
2.301 + throw new IllegalStateException();
2.302 + }
2.303 +
2.304 + /**
2.305 + * Facilitates the creation of simple "function objects" that implement one
2.306 + * or more interfaces by delegation to a provided {@link MethodHandle},
2.307 + * after appropriate type adaptation and partial evaluation of arguments.
2.308 + * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
2.309 + * call sites, to support the <em>lambda expression</em> and <em>method
2.310 + * reference expression</em> features of the Java Programming Language.
2.311 + *
2.312 + * <p>This is the general, more flexible metafactory; a streamlined version
2.313 + * is provided by {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}.
2.314 + * A general description of the behavior of this method is provided
2.315 + * {@link LambdaMetafactory above}.
2.316 + *
2.317 + * <p>The argument list for this method includes three fixed parameters,
2.318 + * corresponding to the parameters automatically stacked by the VM for the
2.319 + * bootstrap method in an {@code invokedynamic} invocation, and an {@code Object[]}
2.320 + * parameter that contains additional parameters. The declared argument
2.321 + * list for this method is:
2.322 + *
2.323 + * <pre>{@code
2.324 + * CallSite altMetafactory(MethodHandles.Lookup caller,
2.325 + * String invokedName,
2.326 + * MethodType invokedType,
2.327 + * Object... args)
2.328 + * }</pre>
2.329 + *
2.330 + * <p>but it behaves as if the argument list is as follows:
2.331 + *
2.332 + * <pre>{@code
2.333 + * CallSite altMetafactory(MethodHandles.Lookup caller,
2.334 + * String invokedName,
2.335 + * MethodType invokedType,
2.336 + * MethodType samMethodType,
2.337 + * MethodHandle implMethod,
2.338 + * MethodType instantiatedMethodType,
2.339 + * int flags,
2.340 + * int markerInterfaceCount, // IF flags has MARKERS set
2.341 + * Class... markerInterfaces, // IF flags has MARKERS set
2.342 + * int bridgeCount, // IF flags has BRIDGES set
2.343 + * MethodType... bridges // IF flags has BRIDGES set
2.344 + * )
2.345 + * }</pre>
2.346 + *
2.347 + * <p>Arguments that appear in the argument list for
2.348 + * {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
2.349 + * have the same specification as in that method. The additional arguments
2.350 + * are interpreted as follows:
2.351 + * <ul>
2.352 + * <li>{@code flags} indicates additional options; this is a bitwise
2.353 + * OR of desired flags. Defined flags are {@link #FLAG_BRIDGES},
2.354 + * {@link #FLAG_MARKERS}, and {@link #FLAG_SERIALIZABLE}.</li>
2.355 + * <li>{@code markerInterfaceCount} is the number of additional interfaces
2.356 + * the function object should implement, and is present if and only if the
2.357 + * {@code FLAG_MARKERS} flag is set.</li>
2.358 + * <li>{@code markerInterfaces} is a variable-length list of additional
2.359 + * interfaces to implement, whose length equals {@code markerInterfaceCount},
2.360 + * and is present if and only if the {@code FLAG_MARKERS} flag is set.</li>
2.361 + * <li>{@code bridgeCount} is the number of additional method signatures
2.362 + * the function object should implement, and is present if and only if
2.363 + * the {@code FLAG_BRIDGES} flag is set.</li>
2.364 + * <li>{@code bridges} is a variable-length list of additional
2.365 + * methods signatures to implement, whose length equals {@code bridgeCount},
2.366 + * and is present if and only if the {@code FLAG_BRIDGES} flag is set.</li>
2.367 + * </ul>
2.368 + *
2.369 + * <p>Each class named by {@code markerInterfaces} is subject to the same
2.370 + * restrictions as {@code Rd}, the return type of {@code invokedType},
2.371 + * as described {@link LambdaMetafactory above}. Each {@code MethodType}
2.372 + * named by {@code bridges} is subject to the same restrictions as
2.373 + * {@code samMethodType}, as described {@link LambdaMetafactory above}.
2.374 + *
2.375 + * <p>When FLAG_SERIALIZABLE is set in {@code flags}, the function objects
2.376 + * will implement {@code Serializable}, and will have a {@code writeReplace}
2.377 + * method that returns an appropriate {@link SerializedLambda}. The
2.378 + * {@code caller} class must have an appropriate {@code $deserializeLambda$}
2.379 + * method, as described in {@link SerializedLambda}.
2.380 + *
2.381 + * <p>When the target of the {@code CallSite} returned from this method is
2.382 + * invoked, the resulting function objects are instances of a class with
2.383 + * the following properties:
2.384 + * <ul>
2.385 + * <li>The class implements the interface named by the return type
2.386 + * of {@code invokedType} and any interfaces named by {@code markerInterfaces}</li>
2.387 + * <li>The class declares methods with the name given by {@code invokedName},
2.388 + * and the signature given by {@code samMethodType} and additional signatures
2.389 + * given by {@code bridges}</li>
2.390 + * <li>The class may override methods from {@code Object}, and may
2.391 + * implement methods related to serialization.</li>
2.392 + * </ul>
2.393 + *
2.394 + * @param caller Represents a lookup context with the accessibility
2.395 + * privileges of the caller. When used with {@code invokedynamic},
2.396 + * this is stacked automatically by the VM.
2.397 + * @param invokedName The name of the method to implement. When used with
2.398 + * {@code invokedynamic}, this is provided by the
2.399 + * {@code NameAndType} of the {@code InvokeDynamic}
2.400 + * structure and is stacked automatically by the VM.
2.401 + * @param invokedType The expected signature of the {@code CallSite}. The
2.402 + * parameter types represent the types of capture variables;
2.403 + * the return type is the interface to implement. When
2.404 + * used with {@code invokedynamic}, this is provided by
2.405 + * the {@code NameAndType} of the {@code InvokeDynamic}
2.406 + * structure and is stacked automatically by the VM.
2.407 + * In the event that the implementation method is an
2.408 + * instance method and this signature has any parameters,
2.409 + * the first parameter in the invocation signature must
2.410 + * correspond to the receiver.
2.411 + * @param args An {@code Object[]} array containing the required
2.412 + * arguments {@code samMethodType}, {@code implMethod},
2.413 + * {@code instantiatedMethodType}, {@code flags}, and any
2.414 + * optional arguments, as described
2.415 + * {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)} above}
2.416 + * @return a CallSite whose target can be used to perform capture, generating
2.417 + * instances of the interface named by {@code invokedType}
2.418 + * @throws LambdaConversionException If any of the linkage invariants
2.419 + * described {@link LambdaMetafactory above}
2.420 + * are violated
2.421 + */
2.422 + public static CallSite altMetafactory(MethodHandles.Lookup caller,
2.423 + String invokedName,
2.424 + MethodType invokedType,
2.425 + Object... args)
2.426 + {
2.427 + throw new IllegalStateException();
2.428 + }
2.429 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandle.java Sun Sep 14 19:27:44 2014 +0200
3.3 @@ -0,0 +1,1168 @@
3.4 +/*
3.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.7 + *
3.8 + * This code is free software; you can redistribute it and/or modify it
3.9 + * under the terms of the GNU General Public License version 2 only, as
3.10 + * published by the Free Software Foundation. Oracle designates this
3.11 + * particular file as subject to the "Classpath" exception as provided
3.12 + * by Oracle in the LICENSE file that accompanied this code.
3.13 + *
3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.17 + * version 2 for more details (a copy is included in the LICENSE file that
3.18 + * accompanied this code).
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License version
3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.23 + *
3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.25 + * or visit www.oracle.com if you need additional information or have any
3.26 + * questions.
3.27 + */
3.28 +
3.29 +package java.lang.invoke;
3.30 +
3.31 +
3.32 +import java.util.*;
3.33 +
3.34 +/**
3.35 + * A method handle is a typed, directly executable reference to an underlying method,
3.36 + * constructor, field, or similar low-level operation, with optional
3.37 + * transformations of arguments or return values.
3.38 + * These transformations are quite general, and include such patterns as
3.39 + * {@linkplain #asType conversion},
3.40 + * {@linkplain #bindTo insertion},
3.41 + * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
3.42 + * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
3.43 + *
3.44 + * <h1>Method handle contents</h1>
3.45 + * Method handles are dynamically and strongly typed according to their parameter and return types.
3.46 + * They are not distinguished by the name or the defining class of their underlying methods.
3.47 + * A method handle must be invoked using a symbolic type descriptor which matches
3.48 + * the method handle's own {@linkplain #type type descriptor}.
3.49 + * <p>
3.50 + * Every method handle reports its type descriptor via the {@link #type type} accessor.
3.51 + * This type descriptor is a {@link java.lang.invoke.MethodType MethodType} object,
3.52 + * whose structure is a series of classes, one of which is
3.53 + * the return type of the method (or {@code void.class} if none).
3.54 + * <p>
3.55 + * A method handle's type controls the types of invocations it accepts,
3.56 + * and the kinds of transformations that apply to it.
3.57 + * <p>
3.58 + * A method handle contains a pair of special invoker methods
3.59 + * called {@link #invokeExact invokeExact} and {@link #invoke invoke}.
3.60 + * Both invoker methods provide direct access to the method handle's
3.61 + * underlying method, constructor, field, or other operation,
3.62 + * as modified by transformations of arguments and return values.
3.63 + * Both invokers accept calls which exactly match the method handle's own type.
3.64 + * The plain, inexact invoker also accepts a range of other call types.
3.65 + * <p>
3.66 + * Method handles are immutable and have no visible state.
3.67 + * Of course, they can be bound to underlying methods or data which exhibit state.
3.68 + * With respect to the Java Memory Model, any method handle will behave
3.69 + * as if all of its (internal) fields are final variables. This means that any method
3.70 + * handle made visible to the application will always be fully formed.
3.71 + * This is true even if the method handle is published through a shared
3.72 + * variable in a data race.
3.73 + * <p>
3.74 + * Method handles cannot be subclassed by the user.
3.75 + * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
3.76 + * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
3.77 + * operation. The programmer should not draw conclusions about a method handle
3.78 + * from its specific class, as the method handle class hierarchy (if any)
3.79 + * may change from time to time or across implementations from different vendors.
3.80 + *
3.81 + * <h1>Method handle compilation</h1>
3.82 + * A Java method call expression naming {@code invokeExact} or {@code invoke}
3.83 + * can invoke a method handle from Java source code.
3.84 + * From the viewpoint of source code, these methods can take any arguments
3.85 + * and their result can be cast to any return type.
3.86 + * Formally this is accomplished by giving the invoker methods
3.87 + * {@code Object} return types and variable arity {@code Object} arguments,
3.88 + * but they have an additional quality called <em>signature polymorphism</em>
3.89 + * which connects this freedom of invocation directly to the JVM execution stack.
3.90 + * <p>
3.91 + * As is usual with virtual methods, source-level calls to {@code invokeExact}
3.92 + * and {@code invoke} compile to an {@code invokevirtual} instruction.
3.93 + * More unusually, the compiler must record the actual argument types,
3.94 + * and may not perform method invocation conversions on the arguments.
3.95 + * Instead, it must push them on the stack according to their own unconverted types.
3.96 + * The method handle object itself is pushed on the stack before the arguments.
3.97 + * The compiler then calls the method handle with a symbolic type descriptor which
3.98 + * describes the argument and return types.
3.99 + * <p>
3.100 + * To issue a complete symbolic type descriptor, the compiler must also determine
3.101 + * the return type. This is based on a cast on the method invocation expression,
3.102 + * if there is one, or else {@code Object} if the invocation is an expression
3.103 + * or else {@code void} if the invocation is a statement.
3.104 + * The cast may be to a primitive type (but not {@code void}).
3.105 + * <p>
3.106 + * As a corner case, an uncasted {@code null} argument is given
3.107 + * a symbolic type descriptor of {@code java.lang.Void}.
3.108 + * The ambiguity with the type {@code Void} is harmless, since there are no references of type
3.109 + * {@code Void} except the null reference.
3.110 + *
3.111 + * <h1>Method handle invocation</h1>
3.112 + * The first time a {@code invokevirtual} instruction is executed
3.113 + * it is linked, by symbolically resolving the names in the instruction
3.114 + * and verifying that the method call is statically legal.
3.115 + * This is true of calls to {@code invokeExact} and {@code invoke}.
3.116 + * In this case, the symbolic type descriptor emitted by the compiler is checked for
3.117 + * correct syntax and names it contains are resolved.
3.118 + * Thus, an {@code invokevirtual} instruction which invokes
3.119 + * a method handle will always link, as long
3.120 + * as the symbolic type descriptor is syntactically well-formed
3.121 + * and the types exist.
3.122 + * <p>
3.123 + * When the {@code invokevirtual} is executed after linking,
3.124 + * the receiving method handle's type is first checked by the JVM
3.125 + * to ensure that it matches the symbolic type descriptor.
3.126 + * If the type match fails, it means that the method which the
3.127 + * caller is invoking is not present on the individual
3.128 + * method handle being invoked.
3.129 + * <p>
3.130 + * In the case of {@code invokeExact}, the type descriptor of the invocation
3.131 + * (after resolving symbolic type names) must exactly match the method type
3.132 + * of the receiving method handle.
3.133 + * In the case of plain, inexact {@code invoke}, the resolved type descriptor
3.134 + * must be a valid argument to the receiver's {@link #asType asType} method.
3.135 + * Thus, plain {@code invoke} is more permissive than {@code invokeExact}.
3.136 + * <p>
3.137 + * After type matching, a call to {@code invokeExact} directly
3.138 + * and immediately invoke the method handle's underlying method
3.139 + * (or other behavior, as the case may be).
3.140 + * <p>
3.141 + * A call to plain {@code invoke} works the same as a call to
3.142 + * {@code invokeExact}, if the symbolic type descriptor specified by the caller
3.143 + * exactly matches the method handle's own type.
3.144 + * If there is a type mismatch, {@code invoke} attempts
3.145 + * to adjust the type of the receiving method handle,
3.146 + * as if by a call to {@link #asType asType},
3.147 + * to obtain an exactly invokable method handle {@code M2}.
3.148 + * This allows a more powerful negotiation of method type
3.149 + * between caller and callee.
3.150 + * <p>
3.151 + * (<em>Note:</em> The adjusted method handle {@code M2} is not directly observable,
3.152 + * and implementations are therefore not required to materialize it.)
3.153 + *
3.154 + * <h1>Invocation checking</h1>
3.155 + * In typical programs, method handle type matching will usually succeed.
3.156 + * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
3.157 + * either directly (in the case of {@code invokeExact}) or indirectly as if
3.158 + * by a failed call to {@code asType} (in the case of {@code invoke}).
3.159 + * <p>
3.160 + * Thus, a method type mismatch which might show up as a linkage error
3.161 + * in a statically typed program can show up as
3.162 + * a dynamic {@code WrongMethodTypeException}
3.163 + * in a program which uses method handles.
3.164 + * <p>
3.165 + * Because method types contain "live" {@code Class} objects,
3.166 + * method type matching takes into account both types names and class loaders.
3.167 + * Thus, even if a method handle {@code M} is created in one
3.168 + * class loader {@code L1} and used in another {@code L2},
3.169 + * method handle calls are type-safe, because the caller's symbolic type
3.170 + * descriptor, as resolved in {@code L2},
3.171 + * is matched against the original callee method's symbolic type descriptor,
3.172 + * as resolved in {@code L1}.
3.173 + * The resolution in {@code L1} happens when {@code M} is created
3.174 + * and its type is assigned, while the resolution in {@code L2} happens
3.175 + * when the {@code invokevirtual} instruction is linked.
3.176 + * <p>
3.177 + * Apart from the checking of type descriptors,
3.178 + * a method handle's capability to call its underlying method is unrestricted.
3.179 + * If a method handle is formed on a non-public method by a class
3.180 + * that has access to that method, the resulting handle can be used
3.181 + * in any place by any caller who receives a reference to it.
3.182 + * <p>
3.183 + * Unlike with the Core Reflection API, where access is checked every time
3.184 + * a reflective method is invoked,
3.185 + * method handle access checking is performed
3.186 + * <a href="MethodHandles.Lookup.html#access">when the method handle is created</a>.
3.187 + * In the case of {@code ldc} (see below), access checking is performed as part of linking
3.188 + * the constant pool entry underlying the constant method handle.
3.189 + * <p>
3.190 + * Thus, handles to non-public methods, or to methods in non-public classes,
3.191 + * should generally be kept secret.
3.192 + * They should not be passed to untrusted code unless their use from
3.193 + * the untrusted code would be harmless.
3.194 + *
3.195 + * <h1>Method handle creation</h1>
3.196 + * Java code can create a method handle that directly accesses
3.197 + * any method, constructor, or field that is accessible to that code.
3.198 + * This is done via a reflective, capability-based API called
3.199 + * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
3.200 + * For example, a static method handle can be obtained
3.201 + * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
3.202 + * There are also conversion methods from Core Reflection API objects,
3.203 + * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
3.204 + * <p>
3.205 + * Like classes and strings, method handles that correspond to accessible
3.206 + * fields, methods, and constructors can also be represented directly
3.207 + * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
3.208 + * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
3.209 + * refers directly to an associated {@code CONSTANT_Methodref},
3.210 + * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
3.211 + * constant pool entry.
3.212 + * (For full details on method handle constants,
3.213 + * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
3.214 + * <p>
3.215 + * Method handles produced by lookups or constant loads from methods or
3.216 + * constructors with the variable arity modifier bit ({@code 0x0080})
3.217 + * have a corresponding variable arity, as if they were defined with
3.218 + * the help of {@link #asVarargsCollector asVarargsCollector}.
3.219 + * <p>
3.220 + * A method reference may refer either to a static or non-static method.
3.221 + * In the non-static case, the method handle type includes an explicit
3.222 + * receiver argument, prepended before any other arguments.
3.223 + * In the method handle's type, the initial receiver argument is typed
3.224 + * according to the class under which the method was initially requested.
3.225 + * (E.g., if a non-static method handle is obtained via {@code ldc},
3.226 + * the type of the receiver is the class named in the constant pool entry.)
3.227 + * <p>
3.228 + * Method handle constants are subject to the same link-time access checks
3.229 + * their corresponding bytecode instructions, and the {@code ldc} instruction
3.230 + * will throw corresponding linkage errors if the bytecode behaviors would
3.231 + * throw such errors.
3.232 + * <p>
3.233 + * As a corollary of this, access to protected members is restricted
3.234 + * to receivers only of the accessing class, or one of its subclasses,
3.235 + * and the accessing class must in turn be a subclass (or package sibling)
3.236 + * of the protected member's defining class.
3.237 + * If a method reference refers to a protected non-static method or field
3.238 + * of a class outside the current package, the receiver argument will
3.239 + * be narrowed to the type of the accessing class.
3.240 + * <p>
3.241 + * When a method handle to a virtual method is invoked, the method is
3.242 + * always looked up in the receiver (that is, the first argument).
3.243 + * <p>
3.244 + * A non-virtual method handle to a specific virtual method implementation
3.245 + * can also be created. These do not perform virtual lookup based on
3.246 + * receiver type. Such a method handle simulates the effect of
3.247 + * an {@code invokespecial} instruction to the same method.
3.248 + *
3.249 + * <h1>Usage examples</h1>
3.250 + * Here are some examples of usage:
3.251 + * <blockquote><pre>{@code
3.252 +Object x, y; String s; int i;
3.253 +MethodType mt; MethodHandle mh;
3.254 +MethodHandles.Lookup lookup = MethodHandles.lookup();
3.255 +// mt is (char,char)String
3.256 +mt = MethodType.methodType(String.class, char.class, char.class);
3.257 +mh = lookup.findVirtual(String.class, "replace", mt);
3.258 +s = (String) mh.invokeExact("daddy",'d','n');
3.259 +// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
3.260 +assertEquals(s, "nanny");
3.261 +// weakly typed invocation (using MHs.invoke)
3.262 +s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
3.263 +assertEquals(s, "savvy");
3.264 +// mt is (Object[])List
3.265 +mt = MethodType.methodType(java.util.List.class, Object[].class);
3.266 +mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
3.267 +assert(mh.isVarargsCollector());
3.268 +x = mh.invoke("one", "two");
3.269 +// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
3.270 +assertEquals(x, java.util.Arrays.asList("one","two"));
3.271 +// mt is (Object,Object,Object)Object
3.272 +mt = MethodType.genericMethodType(3);
3.273 +mh = mh.asType(mt);
3.274 +x = mh.invokeExact((Object)1, (Object)2, (Object)3);
3.275 +// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
3.276 +assertEquals(x, java.util.Arrays.asList(1,2,3));
3.277 +// mt is ()int
3.278 +mt = MethodType.methodType(int.class);
3.279 +mh = lookup.findVirtual(java.util.List.class, "size", mt);
3.280 +i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
3.281 +// invokeExact(Ljava/util/List;)I
3.282 +assert(i == 3);
3.283 +mt = MethodType.methodType(void.class, String.class);
3.284 +mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
3.285 +mh.invokeExact(System.out, "Hello, world.");
3.286 +// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
3.287 + * }</pre></blockquote>
3.288 + * Each of the above calls to {@code invokeExact} or plain {@code invoke}
3.289 + * generates a single invokevirtual instruction with
3.290 + * the symbolic type descriptor indicated in the following comment.
3.291 + * In these examples, the helper method {@code assertEquals} is assumed to
3.292 + * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals}
3.293 + * on its arguments, and asserts that the result is true.
3.294 + *
3.295 + * <h1>Exceptions</h1>
3.296 + * The methods {@code invokeExact} and {@code invoke} are declared
3.297 + * to throw {@link java.lang.Throwable Throwable},
3.298 + * which is to say that there is no static restriction on what a method handle
3.299 + * can throw. Since the JVM does not distinguish between checked
3.300 + * and unchecked exceptions (other than by their class, of course),
3.301 + * there is no particular effect on bytecode shape from ascribing
3.302 + * checked exceptions to method handle invocations. But in Java source
3.303 + * code, methods which perform method handle calls must either explicitly
3.304 + * throw {@code Throwable}, or else must catch all
3.305 + * throwables locally, rethrowing only those which are legal in the context,
3.306 + * and wrapping ones which are illegal.
3.307 + *
3.308 + * <h1><a name="sigpoly"></a>Signature polymorphism</h1>
3.309 + * The unusual compilation and linkage behavior of
3.310 + * {@code invokeExact} and plain {@code invoke}
3.311 + * is referenced by the term <em>signature polymorphism</em>.
3.312 + * As defined in the Java Language Specification,
3.313 + * a signature polymorphic method is one which can operate with
3.314 + * any of a wide range of call signatures and return types.
3.315 + * <p>
3.316 + * In source code, a call to a signature polymorphic method will
3.317 + * compile, regardless of the requested symbolic type descriptor.
3.318 + * As usual, the Java compiler emits an {@code invokevirtual}
3.319 + * instruction with the given symbolic type descriptor against the named method.
3.320 + * The unusual part is that the symbolic type descriptor is derived from
3.321 + * the actual argument and return types, not from the method declaration.
3.322 + * <p>
3.323 + * When the JVM processes bytecode containing signature polymorphic calls,
3.324 + * it will successfully link any such call, regardless of its symbolic type descriptor.
3.325 + * (In order to retain type safety, the JVM will guard such calls with suitable
3.326 + * dynamic type checks, as described elsewhere.)
3.327 + * <p>
3.328 + * Bytecode generators, including the compiler back end, are required to emit
3.329 + * untransformed symbolic type descriptors for these methods.
3.330 + * Tools which determine symbolic linkage are required to accept such
3.331 + * untransformed descriptors, without reporting linkage errors.
3.332 + *
3.333 + * <h1>Interoperation between method handles and the Core Reflection API</h1>
3.334 + * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup Lookup} API,
3.335 + * any class member represented by a Core Reflection API object
3.336 + * can be converted to a behaviorally equivalent method handle.
3.337 + * For example, a reflective {@link java.lang.reflect.Method Method} can
3.338 + * be converted to a method handle using
3.339 + * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
3.340 + * The resulting method handles generally provide more direct and efficient
3.341 + * access to the underlying class members.
3.342 + * <p>
3.343 + * As a special case,
3.344 + * when the Core Reflection API is used to view the signature polymorphic
3.345 + * methods {@code invokeExact} or plain {@code invoke} in this class,
3.346 + * they appear as ordinary non-polymorphic methods.
3.347 + * Their reflective appearance, as viewed by
3.348 + * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
3.349 + * is unaffected by their special status in this API.
3.350 + * For example, {@link java.lang.reflect.Method#getModifiers Method.getModifiers}
3.351 + * will report exactly those modifier bits required for any similarly
3.352 + * declared method, including in this case {@code native} and {@code varargs} bits.
3.353 + * <p>
3.354 + * As with any reflected method, these methods (when reflected) may be
3.355 + * invoked via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}.
3.356 + * However, such reflective calls do not result in method handle invocations.
3.357 + * Such a call, if passed the required argument
3.358 + * (a single one, of type {@code Object[]}), will ignore the argument and
3.359 + * will throw an {@code UnsupportedOperationException}.
3.360 + * <p>
3.361 + * Since {@code invokevirtual} instructions can natively
3.362 + * invoke method handles under any symbolic type descriptor, this reflective view conflicts
3.363 + * with the normal presentation of these methods via bytecodes.
3.364 + * Thus, these two native methods, when reflectively viewed by
3.365 + * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
3.366 + * <p>
3.367 + * In order to obtain an invoker method for a particular type descriptor,
3.368 + * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker},
3.369 + * or {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}.
3.370 + * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
3.371 + * API is also able to return a method handle
3.372 + * to call {@code invokeExact} or plain {@code invoke},
3.373 + * for any specified type descriptor .
3.374 + *
3.375 + * <h1>Interoperation between method handles and Java generics</h1>
3.376 + * A method handle can be obtained on a method, constructor, or field
3.377 + * which is declared with Java generic types.
3.378 + * As with the Core Reflection API, the type of the method handle
3.379 + * will constructed from the erasure of the source-level type.
3.380 + * When a method handle is invoked, the types of its arguments
3.381 + * or the return value cast type may be generic types or type instances.
3.382 + * If this occurs, the compiler will replace those
3.383 + * types by their erasures when it constructs the symbolic type descriptor
3.384 + * for the {@code invokevirtual} instruction.
3.385 + * <p>
3.386 + * Method handles do not represent
3.387 + * their function-like types in terms of Java parameterized (generic) types,
3.388 + * because there are three mismatches between function-like types and parameterized
3.389 + * Java types.
3.390 + * <ul>
3.391 + * <li>Method types range over all possible arities,
3.392 + * from no arguments to up to the <a href="MethodHandle.html#maxarity">maximum number</a> of allowed arguments.
3.393 + * Generics are not variadic, and so cannot represent this.</li>
3.394 + * <li>Method types can specify arguments of primitive types,
3.395 + * which Java generic types cannot range over.</li>
3.396 + * <li>Higher order functions over method handles (combinators) are
3.397 + * often generic across a wide range of function types, including
3.398 + * those of multiple arities. It is impossible to represent such
3.399 + * genericity with a Java type parameter.</li>
3.400 + * </ul>
3.401 + *
3.402 + * <h1><a name="maxarity"></a>Arity limits</h1>
3.403 + * The JVM imposes on all methods and constructors of any kind an absolute
3.404 + * limit of 255 stacked arguments. This limit can appear more restrictive
3.405 + * in certain cases:
3.406 + * <ul>
3.407 + * <li>A {@code long} or {@code double} argument counts (for purposes of arity limits) as two argument slots.
3.408 + * <li>A non-static method consumes an extra argument for the object on which the method is called.
3.409 + * <li>A constructor consumes an extra argument for the object which is being constructed.
3.410 + * <li>Since a method handle’s {@code invoke} method (or other signature-polymorphic method) is non-virtual,
3.411 + * it consumes an extra argument for the method handle itself, in addition to any non-virtual receiver object.
3.412 + * </ul>
3.413 + * These limits imply that certain method handles cannot be created, solely because of the JVM limit on stacked arguments.
3.414 + * For example, if a static JVM method accepts exactly 255 arguments, a method handle cannot be created for it.
3.415 + * Attempts to create method handles with impossible method types lead to an {@link IllegalArgumentException}.
3.416 + * In particular, a method handle’s type must not have an arity of the exact maximum 255.
3.417 + *
3.418 + * @see MethodType
3.419 + * @see MethodHandles
3.420 + * @author John Rose, JSR 292 EG
3.421 + */
3.422 +public abstract class MethodHandle {
3.423 + /**
3.424 + * Internal marker interface which distinguishes (to the Java compiler)
3.425 + * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
3.426 + */
3.427 + @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
3.428 + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
3.429 + @interface PolymorphicSignature { }
3.430 +
3.431 + /**
3.432 + * Reports the type of this method handle.
3.433 + * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
3.434 + * @return the method handle type
3.435 + */
3.436 + public MethodType type() {
3.437 + throw new IllegalStateException();
3.438 + }
3.439 +
3.440 + /**
3.441 + * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
3.442 + * The symbolic type descriptor at the call site of {@code invokeExact} must
3.443 + * exactly match this method handle's {@link #type type}.
3.444 + * No conversions are allowed on arguments or return values.
3.445 + * <p>
3.446 + * When this method is observed via the Core Reflection API,
3.447 + * it will appear as a single native method, taking an object array and returning an object.
3.448 + * If this native method is invoked directly via
3.449 + * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
3.450 + * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
3.451 + * it will throw an {@code UnsupportedOperationException}.
3.452 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.453 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.454 + * @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
3.455 + * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
3.456 + */
3.457 + public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
3.458 +
3.459 + /**
3.460 + * Invokes the method handle, allowing any caller type descriptor,
3.461 + * and optionally performing conversions on arguments and return values.
3.462 + * <p>
3.463 + * If the call site's symbolic type descriptor exactly matches this method handle's {@link #type type},
3.464 + * the call proceeds as if by {@link #invokeExact invokeExact}.
3.465 + * <p>
3.466 + * Otherwise, the call proceeds as if this method handle were first
3.467 + * adjusted by calling {@link #asType asType} to adjust this method handle
3.468 + * to the required type, and then the call proceeds as if by
3.469 + * {@link #invokeExact invokeExact} on the adjusted method handle.
3.470 + * <p>
3.471 + * There is no guarantee that the {@code asType} call is actually made.
3.472 + * If the JVM can predict the results of making the call, it may perform
3.473 + * adaptations directly on the caller's arguments,
3.474 + * and call the target method handle according to its own exact type.
3.475 + * <p>
3.476 + * The resolved type descriptor at the call site of {@code invoke} must
3.477 + * be a valid argument to the receivers {@code asType} method.
3.478 + * In particular, the caller must specify the same argument arity
3.479 + * as the callee's type,
3.480 + * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
3.481 + * <p>
3.482 + * When this method is observed via the Core Reflection API,
3.483 + * it will appear as a single native method, taking an object array and returning an object.
3.484 + * If this native method is invoked directly via
3.485 + * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
3.486 + * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
3.487 + * it will throw an {@code UnsupportedOperationException}.
3.488 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.489 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.490 + * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's symbolic type descriptor
3.491 + * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
3.492 + * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
3.493 + */
3.494 + public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
3.495 +
3.496 + /**
3.497 + * Private method for trusted invocation of a method handle respecting simplified signatures.
3.498 + * Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
3.499 + * <p>
3.500 + * The caller signature is restricted to the following basic types:
3.501 + * Object, int, long, float, double, and void return.
3.502 + * <p>
3.503 + * The caller is responsible for maintaining type correctness by ensuring
3.504 + * that the each outgoing argument value is a member of the range of the corresponding
3.505 + * callee argument type.
3.506 + * (The caller should therefore issue appropriate casts and integer narrowing
3.507 + * operations on outgoing argument values.)
3.508 + * The caller can assume that the incoming result value is part of the range
3.509 + * of the callee's return type.
3.510 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.511 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.512 + */
3.513 + /*non-public*/ final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
3.514 +
3.515 + /**
3.516 + * Private method for trusted invocation of a MemberName of kind {@code REF_invokeVirtual}.
3.517 + * The caller signature is restricted to basic types as with {@code invokeBasic}.
3.518 + * The trailing (not leading) argument must be a MemberName.
3.519 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.520 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.521 + */
3.522 + /*non-public*/ static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
3.523 +
3.524 + /**
3.525 + * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
3.526 + * The caller signature is restricted to basic types as with {@code invokeBasic}.
3.527 + * The trailing (not leading) argument must be a MemberName.
3.528 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.529 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.530 + */
3.531 + /*non-public*/ static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
3.532 +
3.533 + /**
3.534 + * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
3.535 + * The caller signature is restricted to basic types as with {@code invokeBasic}.
3.536 + * The trailing (not leading) argument must be a MemberName.
3.537 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.538 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.539 + */
3.540 + /*non-public*/ static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
3.541 +
3.542 + /**
3.543 + * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
3.544 + * The caller signature is restricted to basic types as with {@code invokeBasic}.
3.545 + * The trailing (not leading) argument must be a MemberName.
3.546 + * @param args the signature-polymorphic parameter list, statically represented using varargs
3.547 + * @return the signature-polymorphic result, statically represented using {@code Object}
3.548 + */
3.549 + /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
3.550 +
3.551 + /**
3.552 + * Performs a variable arity invocation, passing the arguments in the given list
3.553 + * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
3.554 + * which mentions only the type {@code Object}, and whose arity is the length
3.555 + * of the argument list.
3.556 + * <p>
3.557 + * Specifically, execution proceeds as if by the following steps,
3.558 + * although the methods are not guaranteed to be called if the JVM
3.559 + * can predict their effects.
3.560 + * <ul>
3.561 + * <li>Determine the length of the argument array as {@code N}.
3.562 + * For a null reference, {@code N=0}. </li>
3.563 + * <li>Determine the general type {@code TN} of {@code N} arguments as
3.564 + * as {@code TN=MethodType.genericMethodType(N)}.</li>
3.565 + * <li>Force the original target method handle {@code MH0} to the
3.566 + * required type, as {@code MH1 = MH0.asType(TN)}. </li>
3.567 + * <li>Spread the array into {@code N} separate arguments {@code A0, ...}. </li>
3.568 + * <li>Invoke the type-adjusted method handle on the unpacked arguments:
3.569 + * MH1.invokeExact(A0, ...). </li>
3.570 + * <li>Take the return value as an {@code Object} reference. </li>
3.571 + * </ul>
3.572 + * <p>
3.573 + * Because of the action of the {@code asType} step, the following argument
3.574 + * conversions are applied as necessary:
3.575 + * <ul>
3.576 + * <li>reference casting
3.577 + * <li>unboxing
3.578 + * <li>widening primitive conversions
3.579 + * </ul>
3.580 + * <p>
3.581 + * The result returned by the call is boxed if it is a primitive,
3.582 + * or forced to null if the return type is void.
3.583 + * <p>
3.584 + * This call is equivalent to the following code:
3.585 + * <blockquote><pre>{@code
3.586 + * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
3.587 + * Object result = invoker.invokeExact(this, arguments);
3.588 + * }</pre></blockquote>
3.589 + * <p>
3.590 + * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
3.591 + * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
3.592 + * It can therefore be used as a bridge between native or reflective code and method handles.
3.593 + *
3.594 + * @param arguments the arguments to pass to the target
3.595 + * @return the result returned by the target
3.596 + * @throws ClassCastException if an argument cannot be converted by reference casting
3.597 + * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
3.598 + * @throws Throwable anything thrown by the target method invocation
3.599 + * @see MethodHandles#spreadInvoker
3.600 + */
3.601 + public Object invokeWithArguments(Object... arguments) throws Throwable {
3.602 + throw new IllegalStateException();
3.603 + }
3.604 +
3.605 + /**
3.606 + * Performs a variable arity invocation, passing the arguments in the given array
3.607 + * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
3.608 + * which mentions only the type {@code Object}, and whose arity is the length
3.609 + * of the argument array.
3.610 + * <p>
3.611 + * This method is also equivalent to the following code:
3.612 + * <blockquote><pre>{@code
3.613 + * invokeWithArguments(arguments.toArray()
3.614 + * }</pre></blockquote>
3.615 + *
3.616 + * @param arguments the arguments to pass to the target
3.617 + * @return the result returned by the target
3.618 + * @throws NullPointerException if {@code arguments} is a null reference
3.619 + * @throws ClassCastException if an argument cannot be converted by reference casting
3.620 + * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
3.621 + * @throws Throwable anything thrown by the target method invocation
3.622 + */
3.623 + public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
3.624 + return invokeWithArguments(arguments.toArray());
3.625 + }
3.626 +
3.627 + /**
3.628 + * Produces an adapter method handle which adapts the type of the
3.629 + * current method handle to a new type.
3.630 + * The resulting method handle is guaranteed to report a type
3.631 + * which is equal to the desired new type.
3.632 + * <p>
3.633 + * If the original type and new type are equal, returns {@code this}.
3.634 + * <p>
3.635 + * The new method handle, when invoked, will perform the following
3.636 + * steps:
3.637 + * <ul>
3.638 + * <li>Convert the incoming argument list to match the original
3.639 + * method handle's argument list.
3.640 + * <li>Invoke the original method handle on the converted argument list.
3.641 + * <li>Convert any result returned by the original method handle
3.642 + * to the return type of new method handle.
3.643 + * </ul>
3.644 + * <p>
3.645 + * This method provides the crucial behavioral difference between
3.646 + * {@link #invokeExact invokeExact} and plain, inexact {@link #invoke invoke}.
3.647 + * The two methods
3.648 + * perform the same steps when the caller's type descriptor exactly m atches
3.649 + * the callee's, but when the types differ, plain {@link #invoke invoke}
3.650 + * also calls {@code asType} (or some internal equivalent) in order
3.651 + * to match up the caller's and callee's types.
3.652 + * <p>
3.653 + * If the current method is a variable arity method handle
3.654 + * argument list conversion may involve the conversion and collection
3.655 + * of several arguments into an array, as
3.656 + * {@linkplain #asVarargsCollector described elsewhere}.
3.657 + * In every other case, all conversions are applied <em>pairwise</em>,
3.658 + * which means that each argument or return value is converted to
3.659 + * exactly one argument or return value (or no return value).
3.660 + * The applied conversions are defined by consulting the
3.661 + * the corresponding component types of the old and new
3.662 + * method handle types.
3.663 + * <p>
3.664 + * Let <em>T0</em> and <em>T1</em> be corresponding new and old parameter types,
3.665 + * or old and new return types. Specifically, for some valid index {@code i}, let
3.666 + * <em>T0</em>{@code =newType.parameterType(i)} and <em>T1</em>{@code =this.type().parameterType(i)}.
3.667 + * Or else, going the other way for return values, let
3.668 + * <em>T0</em>{@code =this.type().returnType()} and <em>T1</em>{@code =newType.returnType()}.
3.669 + * If the types are the same, the new method handle makes no change
3.670 + * to the corresponding argument or return value (if any).
3.671 + * Otherwise, one of the following conversions is applied
3.672 + * if possible:
3.673 + * <ul>
3.674 + * <li>If <em>T0</em> and <em>T1</em> are references, then a cast to <em>T1</em> is applied.
3.675 + * (The types do not need to be related in any particular way.
3.676 + * This is because a dynamic value of null can convert to any reference type.)
3.677 + * <li>If <em>T0</em> and <em>T1</em> are primitives, then a Java method invocation
3.678 + * conversion (JLS 5.3) is applied, if one exists.
3.679 + * (Specifically, <em>T0</em> must convert to <em>T1</em> by a widening primitive conversion.)
3.680 + * <li>If <em>T0</em> is a primitive and <em>T1</em> a reference,
3.681 + * a Java casting conversion (JLS 5.5) is applied if one exists.
3.682 + * (Specifically, the value is boxed from <em>T0</em> to its wrapper class,
3.683 + * which is then widened as needed to <em>T1</em>.)
3.684 + * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
3.685 + * conversion will be applied at runtime, possibly followed
3.686 + * by a Java method invocation conversion (JLS 5.3)
3.687 + * on the primitive value. (These are the primitive widening conversions.)
3.688 + * <em>T0</em> must be a wrapper class or a supertype of one.
3.689 + * (In the case where <em>T0</em> is Object, these are the conversions
3.690 + * allowed by {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}.)
3.691 + * The unboxing conversion must have a possibility of success, which means that
3.692 + * if <em>T0</em> is not itself a wrapper class, there must exist at least one
3.693 + * wrapper class <em>TW</em> which is a subtype of <em>T0</em> and whose unboxed
3.694 + * primitive value can be widened to <em>T1</em>.
3.695 + * <li>If the return type <em>T1</em> is marked as void, any returned value is discarded
3.696 + * <li>If the return type <em>T0</em> is void and <em>T1</em> a reference, a null value is introduced.
3.697 + * <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
3.698 + * a zero value is introduced.
3.699 + * </ul>
3.700 + * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
3.701 + * because neither corresponds specifically to the <em>dynamic type</em> of any
3.702 + * actual argument or return value.)
3.703 + * <p>
3.704 + * The method handle conversion cannot be made if any one of the required
3.705 + * pairwise conversions cannot be made.
3.706 + * <p>
3.707 + * At runtime, the conversions applied to reference arguments
3.708 + * or return values may require additional runtime checks which can fail.
3.709 + * An unboxing operation may fail because the original reference is null,
3.710 + * causing a {@link java.lang.NullPointerException NullPointerException}.
3.711 + * An unboxing operation or a reference cast may also fail on a reference
3.712 + * to an object of the wrong type,
3.713 + * causing a {@link java.lang.ClassCastException ClassCastException}.
3.714 + * Although an unboxing operation may accept several kinds of wrappers,
3.715 + * if none are available, a {@code ClassCastException} will be thrown.
3.716 + *
3.717 + * @param newType the expected type of the new method handle
3.718 + * @return a method handle which delegates to {@code this} after performing
3.719 + * any necessary argument conversions, and arranges for any
3.720 + * necessary return value conversions
3.721 + * @throws NullPointerException if {@code newType} is a null reference
3.722 + * @throws WrongMethodTypeException if the conversion cannot be made
3.723 + * @see MethodHandles#explicitCastArguments
3.724 + */
3.725 + public MethodHandle asType(MethodType newType) {
3.726 + throw new IllegalStateException();
3.727 + }
3.728 +
3.729 + /**
3.730 + * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
3.731 + * and spreads its elements as positional arguments.
3.732 + * The new method handle adapts, as its <i>target</i>,
3.733 + * the current method handle. The type of the adapter will be
3.734 + * the same as the type of the target, except that the final
3.735 + * {@code arrayLength} parameters of the target's type are replaced
3.736 + * by a single array parameter of type {@code arrayType}.
3.737 + * <p>
3.738 + * If the array element type differs from any of the corresponding
3.739 + * argument types on the original target,
3.740 + * the original target is adapted to take the array elements directly,
3.741 + * as if by a call to {@link #asType asType}.
3.742 + * <p>
3.743 + * When called, the adapter replaces a trailing array argument
3.744 + * by the array's elements, each as its own argument to the target.
3.745 + * (The order of the arguments is preserved.)
3.746 + * They are converted pairwise by casting and/or unboxing
3.747 + * to the types of the trailing parameters of the target.
3.748 + * Finally the target is called.
3.749 + * What the target eventually returns is returned unchanged by the adapter.
3.750 + * <p>
3.751 + * Before calling the target, the adapter verifies that the array
3.752 + * contains exactly enough elements to provide a correct argument count
3.753 + * to the target method handle.
3.754 + * (The array may also be null when zero elements are required.)
3.755 + * <p>
3.756 + * If, when the adapter is called, the supplied array argument does
3.757 + * not have the correct number of elements, the adapter will throw
3.758 + * an {@link IllegalArgumentException} instead of invoking the target.
3.759 + * <p>
3.760 + * Here are some simple examples of array-spreading method handles:
3.761 + * <blockquote><pre>{@code
3.762 +MethodHandle equals = publicLookup()
3.763 + .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
3.764 +assert( (boolean) equals.invokeExact("me", (Object)"me"));
3.765 +assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
3.766 +// spread both arguments from a 2-array:
3.767 +MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
3.768 +assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
3.769 +assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
3.770 +// try to spread from anything but a 2-array:
3.771 +for (int n = 0; n <= 10; n++) {
3.772 + Object[] badArityArgs = (n == 2 ? null : new Object[n]);
3.773 + try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
3.774 + catch (IllegalArgumentException ex) { } // OK
3.775 +}
3.776 +// spread both arguments from a String array:
3.777 +MethodHandle eq2s = equals.asSpreader(String[].class, 2);
3.778 +assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
3.779 +assert(!(boolean) eq2s.invokeExact(new String[]{ "me", "thee" }));
3.780 +// spread second arguments from a 1-array:
3.781 +MethodHandle eq1 = equals.asSpreader(Object[].class, 1);
3.782 +assert( (boolean) eq1.invokeExact("me", new Object[]{ "me" }));
3.783 +assert(!(boolean) eq1.invokeExact("me", new Object[]{ "thee" }));
3.784 +// spread no arguments from a 0-array or null:
3.785 +MethodHandle eq0 = equals.asSpreader(Object[].class, 0);
3.786 +assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));
3.787 +assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));
3.788 +// asSpreader and asCollector are approximate inverses:
3.789 +for (int n = 0; n <= 2; n++) {
3.790 + for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {
3.791 + MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);
3.792 + assert( (boolean) equals2.invokeWithArguments("me", "me"));
3.793 + assert(!(boolean) equals2.invokeWithArguments("me", "thee"));
3.794 + }
3.795 +}
3.796 +MethodHandle caToString = publicLookup()
3.797 + .findStatic(Arrays.class, "toString", methodType(String.class, char[].class));
3.798 +assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
3.799 +MethodHandle caString3 = caToString.asCollector(char[].class, 3);
3.800 +assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
3.801 +MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
3.802 +assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
3.803 + * }</pre></blockquote>
3.804 + * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
3.805 + * @param arrayLength the number of arguments to spread from an incoming array argument
3.806 + * @return a new method handle which spreads its final array argument,
3.807 + * before calling the original method handle
3.808 + * @throws NullPointerException if {@code arrayType} is a null reference
3.809 + * @throws IllegalArgumentException if {@code arrayType} is not an array type,
3.810 + * or if target does not have at least
3.811 + * {@code arrayLength} parameter types,
3.812 + * or if {@code arrayLength} is negative,
3.813 + * or if the resulting method handle's type would have
3.814 + * <a href="MethodHandle.html#maxarity">too many parameters</a>
3.815 + * @throws WrongMethodTypeException if the implied {@code asType} call fails
3.816 + * @see #asCollector
3.817 + */
3.818 + public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
3.819 + throw new IllegalStateException();
3.820 + }
3.821 +
3.822 + /**
3.823 + * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
3.824 + * positional arguments and collects them into an array argument.
3.825 + * The new method handle adapts, as its <i>target</i>,
3.826 + * the current method handle. The type of the adapter will be
3.827 + * the same as the type of the target, except that a single trailing
3.828 + * parameter (usually of type {@code arrayType}) is replaced by
3.829 + * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
3.830 + * <p>
3.831 + * If the array type differs from the final argument type on the original target,
3.832 + * the original target is adapted to take the array type directly,
3.833 + * as if by a call to {@link #asType asType}.
3.834 + * <p>
3.835 + * When called, the adapter replaces its trailing {@code arrayLength}
3.836 + * arguments by a single new array of type {@code arrayType}, whose elements
3.837 + * comprise (in order) the replaced arguments.
3.838 + * Finally the target is called.
3.839 + * What the target eventually returns is returned unchanged by the adapter.
3.840 + * <p>
3.841 + * (The array may also be a shared constant when {@code arrayLength} is zero.)
3.842 + * <p>
3.843 + * (<em>Note:</em> The {@code arrayType} is often identical to the last
3.844 + * parameter type of the original target.
3.845 + * It is an explicit argument for symmetry with {@code asSpreader}, and also
3.846 + * to allow the target to use a simple {@code Object} as its last parameter type.)
3.847 + * <p>
3.848 + * In order to create a collecting adapter which is not restricted to a particular
3.849 + * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
3.850 + * <p>
3.851 + * Here are some examples of array-collecting method handles:
3.852 + * <blockquote><pre>{@code
3.853 +MethodHandle deepToString = publicLookup()
3.854 + .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
3.855 +assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));
3.856 +MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
3.857 +assertEquals(methodType(String.class, Object.class), ts1.type());
3.858 +//assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"})); //FAIL
3.859 +assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"}));
3.860 +// arrayType can be a subtype of Object[]
3.861 +MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
3.862 +assertEquals(methodType(String.class, String.class, String.class), ts2.type());
3.863 +assertEquals("[two, too]", (String) ts2.invokeExact("two", "too"));
3.864 +MethodHandle ts0 = deepToString.asCollector(Object[].class, 0);
3.865 +assertEquals("[]", (String) ts0.invokeExact());
3.866 +// collectors can be nested, Lisp-style
3.867 +MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2);
3.868 +assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D")));
3.869 +// arrayType can be any primitive array type
3.870 +MethodHandle bytesToString = publicLookup()
3.871 + .findStatic(Arrays.class, "toString", methodType(String.class, byte[].class))
3.872 + .asCollector(byte[].class, 3);
3.873 +assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3));
3.874 +MethodHandle longsToString = publicLookup()
3.875 + .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
3.876 + .asCollector(long[].class, 1);
3.877 +assertEquals("[123]", (String) longsToString.invokeExact((long)123));
3.878 + * }</pre></blockquote>
3.879 + * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
3.880 + * @param arrayLength the number of arguments to collect into a new array argument
3.881 + * @return a new method handle which collects some trailing argument
3.882 + * into an array, before calling the original method handle
3.883 + * @throws NullPointerException if {@code arrayType} is a null reference
3.884 + * @throws IllegalArgumentException if {@code arrayType} is not an array type
3.885 + * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
3.886 + * or {@code arrayLength} is not a legal array size,
3.887 + * or the resulting method handle's type would have
3.888 + * <a href="MethodHandle.html#maxarity">too many parameters</a>
3.889 + * @throws WrongMethodTypeException if the implied {@code asType} call fails
3.890 + * @see #asSpreader
3.891 + * @see #asVarargsCollector
3.892 + */
3.893 + public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
3.894 + throw new IllegalStateException();
3.895 + }
3.896 +
3.897 + /**
3.898 + * Makes a <em>variable arity</em> adapter which is able to accept
3.899 + * any number of trailing positional arguments and collect them
3.900 + * into an array argument.
3.901 + * <p>
3.902 + * The type and behavior of the adapter will be the same as
3.903 + * the type and behavior of the target, except that certain
3.904 + * {@code invoke} and {@code asType} requests can lead to
3.905 + * trailing positional arguments being collected into target's
3.906 + * trailing parameter.
3.907 + * Also, the last parameter type of the adapter will be
3.908 + * {@code arrayType}, even if the target has a different
3.909 + * last parameter type.
3.910 + * <p>
3.911 + * This transformation may return {@code this} if the method handle is
3.912 + * already of variable arity and its trailing parameter type
3.913 + * is identical to {@code arrayType}.
3.914 + * <p>
3.915 + * When called with {@link #invokeExact invokeExact}, the adapter invokes
3.916 + * the target with no argument changes.
3.917 + * (<em>Note:</em> This behavior is different from a
3.918 + * {@linkplain #asCollector fixed arity collector},
3.919 + * since it accepts a whole array of indeterminate length,
3.920 + * rather than a fixed number of arguments.)
3.921 + * <p>
3.922 + * When called with plain, inexact {@link #invoke invoke}, if the caller
3.923 + * type is the same as the adapter, the adapter invokes the target as with
3.924 + * {@code invokeExact}.
3.925 + * (This is the normal behavior for {@code invoke} when types match.)
3.926 + * <p>
3.927 + * Otherwise, if the caller and adapter arity are the same, and the
3.928 + * trailing parameter type of the caller is a reference type identical to
3.929 + * or assignable to the trailing parameter type of the adapter,
3.930 + * the arguments and return values are converted pairwise,
3.931 + * as if by {@link #asType asType} on a fixed arity
3.932 + * method handle.
3.933 + * <p>
3.934 + * Otherwise, the arities differ, or the adapter's trailing parameter
3.935 + * type is not assignable from the corresponding caller type.
3.936 + * In this case, the adapter replaces all trailing arguments from
3.937 + * the original trailing argument position onward, by
3.938 + * a new array of type {@code arrayType}, whose elements
3.939 + * comprise (in order) the replaced arguments.
3.940 + * <p>
3.941 + * The caller type must provides as least enough arguments,
3.942 + * and of the correct type, to satisfy the target's requirement for
3.943 + * positional arguments before the trailing array argument.
3.944 + * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
3.945 + * where {@code N} is the arity of the target.
3.946 + * Also, there must exist conversions from the incoming arguments
3.947 + * to the target's arguments.
3.948 + * As with other uses of plain {@code invoke}, if these basic
3.949 + * requirements are not fulfilled, a {@code WrongMethodTypeException}
3.950 + * may be thrown.
3.951 + * <p>
3.952 + * In all cases, what the target eventually returns is returned unchanged by the adapter.
3.953 + * <p>
3.954 + * In the final case, it is exactly as if the target method handle were
3.955 + * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
3.956 + * to the arity required by the caller type.
3.957 + * (As with {@code asCollector}, if the array length is zero,
3.958 + * a shared constant may be used instead of a new array.
3.959 + * If the implied call to {@code asCollector} would throw
3.960 + * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
3.961 + * the call to the variable arity adapter must throw
3.962 + * {@code WrongMethodTypeException}.)
3.963 + * <p>
3.964 + * The behavior of {@link #asType asType} is also specialized for
3.965 + * variable arity adapters, to maintain the invariant that
3.966 + * plain, inexact {@code invoke} is always equivalent to an {@code asType}
3.967 + * call to adjust the target type, followed by {@code invokeExact}.
3.968 + * Therefore, a variable arity adapter responds
3.969 + * to an {@code asType} request by building a fixed arity collector,
3.970 + * if and only if the adapter and requested type differ either
3.971 + * in arity or trailing argument type.
3.972 + * The resulting fixed arity collector has its type further adjusted
3.973 + * (if necessary) to the requested type by pairwise conversion,
3.974 + * as if by another application of {@code asType}.
3.975 + * <p>
3.976 + * When a method handle is obtained by executing an {@code ldc} instruction
3.977 + * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
3.978 + * as a variable arity method (with the modifier bit {@code 0x0080}),
3.979 + * the method handle will accept multiple arities, as if the method handle
3.980 + * constant were created by means of a call to {@code asVarargsCollector}.
3.981 + * <p>
3.982 + * In order to create a collecting adapter which collects a predetermined
3.983 + * number of arguments, and whose type reflects this predetermined number,
3.984 + * use {@link #asCollector asCollector} instead.
3.985 + * <p>
3.986 + * No method handle transformations produce new method handles with
3.987 + * variable arity, unless they are documented as doing so.
3.988 + * Therefore, besides {@code asVarargsCollector},
3.989 + * all methods in {@code MethodHandle} and {@code MethodHandles}
3.990 + * will return a method handle with fixed arity,
3.991 + * except in the cases where they are specified to return their original
3.992 + * operand (e.g., {@code asType} of the method handle's own type).
3.993 + * <p>
3.994 + * Calling {@code asVarargsCollector} on a method handle which is already
3.995 + * of variable arity will produce a method handle with the same type and behavior.
3.996 + * It may (or may not) return the original variable arity method handle.
3.997 + * <p>
3.998 + * Here is an example, of a list-making variable arity method handle:
3.999 + * <blockquote><pre>{@code
3.1000 +MethodHandle deepToString = publicLookup()
3.1001 + .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
3.1002 +MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
3.1003 +assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));
3.1004 +assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));
3.1005 +assertEquals("[won]", (String) ts1.invoke( "won" ));
3.1006 +assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
3.1007 +// findStatic of Arrays.asList(...) produces a variable arity method handle:
3.1008 +MethodHandle asList = publicLookup()
3.1009 + .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
3.1010 +assertEquals(methodType(List.class, Object[].class), asList.type());
3.1011 +assert(asList.isVarargsCollector());
3.1012 +assertEquals("[]", asList.invoke().toString());
3.1013 +assertEquals("[1]", asList.invoke(1).toString());
3.1014 +assertEquals("[two, too]", asList.invoke("two", "too").toString());
3.1015 +String[] argv = { "three", "thee", "tee" };
3.1016 +assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
3.1017 +assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
3.1018 +List ls = (List) asList.invoke((Object)argv);
3.1019 +assertEquals(1, ls.size());
3.1020 +assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
3.1021 + * }</pre></blockquote>
3.1022 + * <p style="font-size:smaller;">
3.1023 + * <em>Discussion:</em>
3.1024 + * These rules are designed as a dynamically-typed variation
3.1025 + * of the Java rules for variable arity methods.
3.1026 + * In both cases, callers to a variable arity method or method handle
3.1027 + * can either pass zero or more positional arguments, or else pass
3.1028 + * pre-collected arrays of any length. Users should be aware of the
3.1029 + * special role of the final argument, and of the effect of a
3.1030 + * type match on that final argument, which determines whether
3.1031 + * or not a single trailing argument is interpreted as a whole
3.1032 + * array or a single element of an array to be collected.
3.1033 + * Note that the dynamic type of the trailing argument has no
3.1034 + * effect on this decision, only a comparison between the symbolic
3.1035 + * type descriptor of the call site and the type descriptor of the method handle.)
3.1036 + *
3.1037 + * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
3.1038 + * @return a new method handle which can collect any number of trailing arguments
3.1039 + * into an array, before calling the original method handle
3.1040 + * @throws NullPointerException if {@code arrayType} is a null reference
3.1041 + * @throws IllegalArgumentException if {@code arrayType} is not an array type
3.1042 + * or {@code arrayType} is not assignable to this method handle's trailing parameter type
3.1043 + * @see #asCollector
3.1044 + * @see #isVarargsCollector
3.1045 + * @see #asFixedArity
3.1046 + */
3.1047 + public MethodHandle asVarargsCollector(Class<?> arrayType) {
3.1048 + throw new IllegalStateException();
3.1049 + }
3.1050 +
3.1051 + /**
3.1052 + * Determines if this method handle
3.1053 + * supports {@linkplain #asVarargsCollector variable arity} calls.
3.1054 + * Such method handles arise from the following sources:
3.1055 + * <ul>
3.1056 + * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
3.1057 + * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
3.1058 + * which resolves to a variable arity Java method or constructor
3.1059 + * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
3.1060 + * which resolves to a variable arity Java method or constructor
3.1061 + * </ul>
3.1062 + * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
3.1063 + * @see #asVarargsCollector
3.1064 + * @see #asFixedArity
3.1065 + */
3.1066 + public boolean isVarargsCollector() {
3.1067 + return false;
3.1068 + }
3.1069 +
3.1070 + /**
3.1071 + * Makes a <em>fixed arity</em> method handle which is otherwise
3.1072 + * equivalent to the current method handle.
3.1073 + * <p>
3.1074 + * If the current method handle is not of
3.1075 + * {@linkplain #asVarargsCollector variable arity},
3.1076 + * the current method handle is returned.
3.1077 + * This is true even if the current method handle
3.1078 + * could not be a valid input to {@code asVarargsCollector}.
3.1079 + * <p>
3.1080 + * Otherwise, the resulting fixed-arity method handle has the same
3.1081 + * type and behavior of the current method handle,
3.1082 + * except that {@link #isVarargsCollector isVarargsCollector}
3.1083 + * will be false.
3.1084 + * The fixed-arity method handle may (or may not) be the
3.1085 + * a previous argument to {@code asVarargsCollector}.
3.1086 + * <p>
3.1087 + * Here is an example, of a list-making variable arity method handle:
3.1088 + * <blockquote><pre>{@code
3.1089 +MethodHandle asListVar = publicLookup()
3.1090 + .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
3.1091 + .asVarargsCollector(Object[].class);
3.1092 +MethodHandle asListFix = asListVar.asFixedArity();
3.1093 +assertEquals("[1]", asListVar.invoke(1).toString());
3.1094 +Exception caught = null;
3.1095 +try { asListFix.invoke((Object)1); }
3.1096 +catch (Exception ex) { caught = ex; }
3.1097 +assert(caught instanceof ClassCastException);
3.1098 +assertEquals("[two, too]", asListVar.invoke("two", "too").toString());
3.1099 +try { asListFix.invoke("two", "too"); }
3.1100 +catch (Exception ex) { caught = ex; }
3.1101 +assert(caught instanceof WrongMethodTypeException);
3.1102 +Object[] argv = { "three", "thee", "tee" };
3.1103 +assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
3.1104 +assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString());
3.1105 +assertEquals(1, ((List) asListVar.invoke((Object)argv)).size());
3.1106 +assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
3.1107 + * }</pre></blockquote>
3.1108 + *
3.1109 + * @return a new method handle which accepts only a fixed number of arguments
3.1110 + * @see #asVarargsCollector
3.1111 + * @see #isVarargsCollector
3.1112 + */
3.1113 + public MethodHandle asFixedArity() {
3.1114 + assert(!isVarargsCollector());
3.1115 + return this;
3.1116 + }
3.1117 +
3.1118 + /**
3.1119 + * Binds a value {@code x} to the first argument of a method handle, without invoking it.
3.1120 + * The new method handle adapts, as its <i>target</i>,
3.1121 + * the current method handle by binding it to the given argument.
3.1122 + * The type of the bound handle will be
3.1123 + * the same as the type of the target, except that a single leading
3.1124 + * reference parameter will be omitted.
3.1125 + * <p>
3.1126 + * When called, the bound handle inserts the given value {@code x}
3.1127 + * as a new leading argument to the target. The other arguments are
3.1128 + * also passed unchanged.
3.1129 + * What the target eventually returns is returned unchanged by the bound handle.
3.1130 + * <p>
3.1131 + * The reference {@code x} must be convertible to the first parameter
3.1132 + * type of the target.
3.1133 + * <p>
3.1134 + * (<em>Note:</em> Because method handles are immutable, the target method handle
3.1135 + * retains its original type and behavior.)
3.1136 + * @param x the value to bind to the first argument of the target
3.1137 + * @return a new method handle which prepends the given value to the incoming
3.1138 + * argument list, before calling the original method handle
3.1139 + * @throws IllegalArgumentException if the target does not have a
3.1140 + * leading parameter type that is a reference type
3.1141 + * @throws ClassCastException if {@code x} cannot be converted
3.1142 + * to the leading parameter type of the target
3.1143 + * @see MethodHandles#insertArguments
3.1144 + */
3.1145 + public MethodHandle bindTo(Object x) {
3.1146 + throw new IllegalStateException();
3.1147 + }
3.1148 +
3.1149 + /**
3.1150 + * Returns a string representation of the method handle,
3.1151 + * starting with the string {@code "MethodHandle"} and
3.1152 + * ending with the string representation of the method handle's type.
3.1153 + * In other words, this method returns a string equal to the value of:
3.1154 + * <blockquote><pre>{@code
3.1155 + * "MethodHandle" + type().toString()
3.1156 + * }</pre></blockquote>
3.1157 + * <p>
3.1158 + * (<em>Note:</em> Future releases of this API may add further information
3.1159 + * to the string representation.
3.1160 + * Therefore, the present syntax should not be parsed by applications.)
3.1161 + *
3.1162 + * @return a string representation of the method handle
3.1163 + */
3.1164 + @Override
3.1165 + public String toString() {
3.1166 + return standardString();
3.1167 + }
3.1168 + String standardString() {
3.1169 + throw new IllegalStateException();
3.1170 + }
3.1171 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandles.java Sun Sep 14 19:27:44 2014 +0200
4.3 @@ -0,0 +1,1222 @@
4.4 +/*
4.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.7 + *
4.8 + * This code is free software; you can redistribute it and/or modify it
4.9 + * under the terms of the GNU General Public License version 2 only, as
4.10 + * published by the Free Software Foundation. Oracle designates this
4.11 + * particular file as subject to the "Classpath" exception as provided
4.12 + * by Oracle in the LICENSE file that accompanied this code.
4.13 + *
4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4.17 + * version 2 for more details (a copy is included in the LICENSE file that
4.18 + * accompanied this code).
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License version
4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4.23 + *
4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4.25 + * or visit www.oracle.com if you need additional information or have any
4.26 + * questions.
4.27 + */
4.28 +
4.29 +package java.lang.invoke;
4.30 +
4.31 +import java.lang.reflect.*;
4.32 +
4.33 +/**
4.34 + * This class consists exclusively of static methods that operate on or return
4.35 + * method handles. They fall into several categories:
4.36 + * <ul>
4.37 + * <li>Lookup methods which help create method handles for methods and fields.
4.38 + * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
4.39 + * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
4.40 + * </ul>
4.41 + * <p>
4.42 + * @author John Rose, JSR 292 EG
4.43 + * @since 1.7
4.44 + */
4.45 +public class MethodHandles {
4.46 +
4.47 + private MethodHandles() { } // do not instantiate
4.48 +
4.49 + //// Method handle creation from ordinary methods.
4.50 +
4.51 + /**
4.52 + * Returns a {@link Lookup lookup object} with
4.53 + * full capabilities to emulate all supported bytecode behaviors of the caller.
4.54 + * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
4.55 + * Factory methods on the lookup object can create
4.56 + * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
4.57 + * for any member that the caller has access to via bytecodes,
4.58 + * including protected and private fields and methods.
4.59 + * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
4.60 + * Do not store it in place where untrusted code can access it.
4.61 + * <p>
4.62 + * This method is caller sensitive, which means that it may return different
4.63 + * values to different callers.
4.64 + * <p>
4.65 + * For any given caller class {@code C}, the lookup object returned by this call
4.66 + * has equivalent capabilities to any lookup object
4.67 + * supplied by the JVM to the bootstrap method of an
4.68 + * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
4.69 + * executing in the same caller class {@code C}.
4.70 + * @return a lookup object for the caller of this method, with private access
4.71 + */
4.72 +// @CallerSensitive
4.73 + public static Lookup lookup() {
4.74 + throw new IllegalStateException("Implement me!");
4.75 +// return new Lookup(Reflection.getCallerClass());
4.76 + }
4.77 +
4.78 + /**
4.79 + * Returns a {@link Lookup lookup object} which is trusted minimally.
4.80 + * It can only be used to create method handles to
4.81 + * publicly accessible fields and methods.
4.82 + * <p>
4.83 + * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
4.84 + * of this lookup object will be {@link java.lang.Object}.
4.85 + *
4.86 + * <p style="font-size:smaller;">
4.87 + * <em>Discussion:</em>
4.88 + * The lookup class can be changed to any other class {@code C} using an expression of the form
4.89 + * {@link Lookup#in publicLookup().in(C.class)}.
4.90 + * Since all classes have equal access to public names,
4.91 + * such a change would confer no new access rights.
4.92 + * A public lookup object is always subject to
4.93 + * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
4.94 + * Also, it cannot access
4.95 + * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
4.96 + * @return a lookup object which is trusted minimally
4.97 + */
4.98 + public static Lookup publicLookup() {
4.99 + return Lookup.PUBLIC_LOOKUP;
4.100 + }
4.101 +
4.102 + /**
4.103 + * Performs an unchecked "crack" of a
4.104 + * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
4.105 + * The result is as if the user had obtained a lookup object capable enough
4.106 + * to crack the target method handle, called
4.107 + * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
4.108 + * on the target to obtain its symbolic reference, and then called
4.109 + * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
4.110 + * to resolve the symbolic reference to a member.
4.111 + * <p>
4.112 + * If there is a security manager, its {@code checkPermission} method
4.113 + * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
4.114 + * @param <T> the desired type of the result, either {@link Member} or a subtype
4.115 + * @param target a direct method handle to crack into symbolic reference components
4.116 + * @param expected a class object representing the desired result type {@code T}
4.117 + * @return a reference to the method, constructor, or field object
4.118 + * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
4.119 + * @exception NullPointerException if either argument is {@code null}
4.120 + * @exception IllegalArgumentException if the target is not a direct method handle
4.121 + * @exception ClassCastException if the member is not of the expected type
4.122 + * @since 1.8
4.123 + */
4.124 + public static <T extends Member> T
4.125 + reflectAs(Class<T> expected, MethodHandle target) {
4.126 + throw new IllegalStateException();
4.127 + }
4.128 + // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
4.129 +// static final private java.security.Permission ACCESS_PERMISSION =
4.130 +// new ReflectPermission("suppressAccessChecks");
4.131 +
4.132 + static Lookup findFor(Class<?> clazz) {
4.133 + Object o = clazz;
4.134 + if (o instanceof Class) {
4.135 + return new Lookup(clazz, Lookup.ALL_MODES);
4.136 + }
4.137 + throw new IllegalArgumentException("Expecting class: " + o);
4.138 + }
4.139 +
4.140 + /**
4.141 + * A <em>lookup object</em> is a factory for creating method handles,
4.142 + * when the creation requires access checking.
4.143 + * Method handles do not perform
4.144 + * access checks when they are called, but rather when they are created.
4.145 + * Therefore, method handle access
4.146 + * restrictions must be enforced when a method handle is created.
4.147 + * The caller class against which those restrictions are enforced
4.148 + * is known as the {@linkplain #lookupClass lookup class}.
4.149 + * <p>
4.150 + * A lookup class which needs to create method handles will call
4.151 + * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
4.152 + * When the {@code Lookup} factory object is created, the identity of the lookup class is
4.153 + * determined, and securely stored in the {@code Lookup} object.
4.154 + * The lookup class (or its delegates) may then use factory methods
4.155 + * on the {@code Lookup} object to create method handles for access-checked members.
4.156 + * This includes all methods, constructors, and fields which are allowed to the lookup class,
4.157 + * even private ones.
4.158 + *
4.159 + * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
4.160 + * The factory methods on a {@code Lookup} object correspond to all major
4.161 + * use cases for methods, constructors, and fields.
4.162 + * Each method handle created by a factory method is the functional
4.163 + * equivalent of a particular <em>bytecode behavior</em>.
4.164 + * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
4.165 + * Here is a summary of the correspondence between these factory methods and
4.166 + * the behavior the resulting method handles:
4.167 + * <table border=1 cellpadding=5 summary="lookup method behaviors">
4.168 + * <tr>
4.169 + * <th><a name="equiv"></a>lookup expression</th>
4.170 + * <th>member</th>
4.171 + * <th>bytecode behavior</th>
4.172 + * </tr>
4.173 + * <tr>
4.174 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
4.175 + * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
4.176 + * </tr>
4.177 + * <tr>
4.178 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
4.179 + * <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
4.180 + * </tr>
4.181 + * <tr>
4.182 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
4.183 + * <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
4.184 + * </tr>
4.185 + * <tr>
4.186 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
4.187 + * <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
4.188 + * </tr>
4.189 + * <tr>
4.190 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
4.191 + * <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
4.192 + * </tr>
4.193 + * <tr>
4.194 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
4.195 + * <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
4.196 + * </tr>
4.197 + * <tr>
4.198 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
4.199 + * <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
4.200 + * </tr>
4.201 + * <tr>
4.202 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
4.203 + * <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
4.204 + * </tr>
4.205 + * <tr>
4.206 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
4.207 + * <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
4.208 + * </tr>
4.209 + * <tr>
4.210 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
4.211 + * <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
4.212 + * </tr>
4.213 + * <tr>
4.214 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
4.215 + * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
4.216 + * </tr>
4.217 + * <tr>
4.218 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
4.219 + * <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
4.220 + * </tr>
4.221 + * <tr>
4.222 + * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
4.223 + * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
4.224 + * </tr>
4.225 + * </table>
4.226 + *
4.227 + * Here, the type {@code C} is the class or interface being searched for a member,
4.228 + * documented as a parameter named {@code refc} in the lookup methods.
4.229 + * The method type {@code MT} is composed from the return type {@code T}
4.230 + * and the sequence of argument types {@code A*}.
4.231 + * The constructor also has a sequence of argument types {@code A*} and
4.232 + * is deemed to return the newly-created object of type {@code C}.
4.233 + * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
4.234 + * The formal parameter {@code this} stands for the self-reference of type {@code C};
4.235 + * if it is present, it is always the leading argument to the method handle invocation.
4.236 + * (In the case of some {@code protected} members, {@code this} may be
4.237 + * restricted in type to the lookup class; see below.)
4.238 + * The name {@code arg} stands for all the other method handle arguments.
4.239 + * In the code examples for the Core Reflection API, the name {@code thisOrNull}
4.240 + * stands for a null reference if the accessed method or field is static,
4.241 + * and {@code this} otherwise.
4.242 + * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
4.243 + * for reflective objects corresponding to the given members.
4.244 + * <p>
4.245 + * In cases where the given member is of variable arity (i.e., a method or constructor)
4.246 + * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
4.247 + * In all other cases, the returned method handle will be of fixed arity.
4.248 + * <p style="font-size:smaller;">
4.249 + * <em>Discussion:</em>
4.250 + * The equivalence between looked-up method handles and underlying
4.251 + * class members and bytecode behaviors
4.252 + * can break down in a few ways:
4.253 + * <ul style="font-size:smaller;">
4.254 + * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
4.255 + * the lookup can still succeed, even when there is no equivalent
4.256 + * Java expression or bytecoded constant.
4.257 + * <li>Likewise, if {@code T} or {@code MT}
4.258 + * is not symbolically accessible from the lookup class's loader,
4.259 + * the lookup can still succeed.
4.260 + * For example, lookups for {@code MethodHandle.invokeExact} and
4.261 + * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
4.262 + * <li>If there is a security manager installed, it can forbid the lookup
4.263 + * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
4.264 + * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
4.265 + * constant is not subject to security manager checks.
4.266 + * <li>If the looked-up method has a
4.267 + * <a href="MethodHandle.html#maxarity">very large arity</a>,
4.268 + * the method handle creation may fail, due to the method handle
4.269 + * type having too many parameters.
4.270 + * </ul>
4.271 + *
4.272 + * <h1><a name="access"></a>Access checking</h1>
4.273 + * Access checks are applied in the factory methods of {@code Lookup},
4.274 + * when a method handle is created.
4.275 + * This is a key difference from the Core Reflection API, since
4.276 + * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
4.277 + * performs access checking against every caller, on every call.
4.278 + * <p>
4.279 + * All access checks start from a {@code Lookup} object, which
4.280 + * compares its recorded lookup class against all requests to
4.281 + * create method handles.
4.282 + * A single {@code Lookup} object can be used to create any number
4.283 + * of access-checked method handles, all checked against a single
4.284 + * lookup class.
4.285 + * <p>
4.286 + * A {@code Lookup} object can be shared with other trusted code,
4.287 + * such as a metaobject protocol.
4.288 + * A shared {@code Lookup} object delegates the capability
4.289 + * to create method handles on private members of the lookup class.
4.290 + * Even if privileged code uses the {@code Lookup} object,
4.291 + * the access checking is confined to the privileges of the
4.292 + * original lookup class.
4.293 + * <p>
4.294 + * A lookup can fail, because
4.295 + * the containing class is not accessible to the lookup class, or
4.296 + * because the desired class member is missing, or because the
4.297 + * desired class member is not accessible to the lookup class, or
4.298 + * because the lookup object is not trusted enough to access the member.
4.299 + * In any of these cases, a {@code ReflectiveOperationException} will be
4.300 + * thrown from the attempted lookup. The exact class will be one of
4.301 + * the following:
4.302 + * <ul>
4.303 + * <li>NoSuchMethodException — if a method is requested but does not exist
4.304 + * <li>NoSuchFieldException — if a field is requested but does not exist
4.305 + * <li>IllegalAccessException — if the member exists but an access check fails
4.306 + * </ul>
4.307 + * <p>
4.308 + * In general, the conditions under which a method handle may be
4.309 + * looked up for a method {@code M} are no more restrictive than the conditions
4.310 + * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
4.311 + * Where the JVM would raise exceptions like {@code NoSuchMethodError},
4.312 + * a method handle lookup will generally raise a corresponding
4.313 + * checked exception, such as {@code NoSuchMethodException}.
4.314 + * And the effect of invoking the method handle resulting from the lookup
4.315 + * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
4.316 + * to executing the compiled, verified, and resolved call to {@code M}.
4.317 + * The same point is true of fields and constructors.
4.318 + * <p style="font-size:smaller;">
4.319 + * <em>Discussion:</em>
4.320 + * Access checks only apply to named and reflected methods,
4.321 + * constructors, and fields.
4.322 + * Other method handle creation methods, such as
4.323 + * {@link MethodHandle#asType MethodHandle.asType},
4.324 + * do not require any access checks, and are used
4.325 + * independently of any {@code Lookup} object.
4.326 + * <p>
4.327 + * If the desired member is {@code protected}, the usual JVM rules apply,
4.328 + * including the requirement that the lookup class must be either be in the
4.329 + * same package as the desired member, or must inherit that member.
4.330 + * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
4.331 + * In addition, if the desired member is a non-static field or method
4.332 + * in a different package, the resulting method handle may only be applied
4.333 + * to objects of the lookup class or one of its subclasses.
4.334 + * This requirement is enforced by narrowing the type of the leading
4.335 + * {@code this} parameter from {@code C}
4.336 + * (which will necessarily be a superclass of the lookup class)
4.337 + * to the lookup class itself.
4.338 + * <p>
4.339 + * The JVM imposes a similar requirement on {@code invokespecial} instruction,
4.340 + * that the receiver argument must match both the resolved method <em>and</em>
4.341 + * the current class. Again, this requirement is enforced by narrowing the
4.342 + * type of the leading parameter to the resulting method handle.
4.343 + * (See the Java Virtual Machine Specification, section 4.10.1.9.)
4.344 + * <p>
4.345 + * The JVM represents constructors and static initializer blocks as internal methods
4.346 + * with special names ({@code "<init>"} and {@code "<clinit>"}).
4.347 + * The internal syntax of invocation instructions allows them to refer to such internal
4.348 + * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
4.349 + * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
4.350 + * <p>
4.351 + * In some cases, access between nested classes is obtained by the Java compiler by creating
4.352 + * an wrapper method to access a private method of another class
4.353 + * in the same top-level declaration.
4.354 + * For example, a nested class {@code C.D}
4.355 + * can access private members within other related classes such as
4.356 + * {@code C}, {@code C.D.E}, or {@code C.B},
4.357 + * but the Java compiler may need to generate wrapper methods in
4.358 + * those related classes. In such cases, a {@code Lookup} object on
4.359 + * {@code C.E} would be unable to those private members.
4.360 + * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
4.361 + * which can transform a lookup on {@code C.E} into one on any of those other
4.362 + * classes, without special elevation of privilege.
4.363 + * <p>
4.364 + * The accesses permitted to a given lookup object may be limited,
4.365 + * according to its set of {@link #lookupModes lookupModes},
4.366 + * to a subset of members normally accessible to the lookup class.
4.367 + * For example, the {@link MethodHandles#publicLookup publicLookup}
4.368 + * method produces a lookup object which is only allowed to access
4.369 + * public members in public classes.
4.370 + * The caller sensitive method {@link MethodHandles#lookup lookup}
4.371 + * produces a lookup object with full capabilities relative to
4.372 + * its caller class, to emulate all supported bytecode behaviors.
4.373 + * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
4.374 + * with fewer access modes than the original lookup object.
4.375 + *
4.376 + * <p style="font-size:smaller;">
4.377 + * <a name="privacc"></a>
4.378 + * <em>Discussion of private access:</em>
4.379 + * We say that a lookup has <em>private access</em>
4.380 + * if its {@linkplain #lookupModes lookup modes}
4.381 + * include the possibility of accessing {@code private} members.
4.382 + * As documented in the relevant methods elsewhere,
4.383 + * only lookups with private access possess the following capabilities:
4.384 + * <ul style="font-size:smaller;">
4.385 + * <li>access private fields, methods, and constructors of the lookup class
4.386 + * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
4.387 + * such as {@code Class.forName}
4.388 + * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
4.389 + * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
4.390 + * for classes accessible to the lookup class
4.391 + * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
4.392 + * within the same package member
4.393 + * </ul>
4.394 + * <p style="font-size:smaller;">
4.395 + * Each of these permissions is a consequence of the fact that a lookup object
4.396 + * with private access can be securely traced back to an originating class,
4.397 + * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
4.398 + * can be reliably determined and emulated by method handles.
4.399 + *
4.400 + * <h1><a name="secmgr"></a>Security manager interactions</h1>
4.401 + * Although bytecode instructions can only refer to classes in
4.402 + * a related class loader, this API can search for methods in any
4.403 + * class, as long as a reference to its {@code Class} object is
4.404 + * available. Such cross-loader references are also possible with the
4.405 + * Core Reflection API, and are impossible to bytecode instructions
4.406 + * such as {@code invokestatic} or {@code getfield}.
4.407 + * There is a {@linkplain java.lang.SecurityManager security manager API}
4.408 + * to allow applications to check such cross-loader references.
4.409 + * These checks apply to both the {@code MethodHandles.Lookup} API
4.410 + * and the Core Reflection API
4.411 + * (as found on {@link java.lang.Class Class}).
4.412 + * <p>
4.413 + * If a security manager is present, member lookups are subject to
4.414 + * additional checks.
4.415 + * From one to three calls are made to the security manager.
4.416 + * Any of these calls can refuse access by throwing a
4.417 + * {@link java.lang.SecurityException SecurityException}.
4.418 + * Define {@code smgr} as the security manager,
4.419 + * {@code lookc} as the lookup class of the current lookup object,
4.420 + * {@code refc} as the containing class in which the member
4.421 + * is being sought, and {@code defc} as the class in which the
4.422 + * member is actually defined.
4.423 + * The value {@code lookc} is defined as <em>not present</em>
4.424 + * if the current lookup object does not have
4.425 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
4.426 + * The calls are made according to the following rules:
4.427 + * <ul>
4.428 + * <li><b>Step 1:</b>
4.429 + * If {@code lookc} is not present, or if its class loader is not
4.430 + * the same as or an ancestor of the class loader of {@code refc},
4.431 + * then {@link SecurityManager#checkPackageAccess
4.432 + * smgr.checkPackageAccess(refcPkg)} is called,
4.433 + * where {@code refcPkg} is the package of {@code refc}.
4.434 + * <li><b>Step 2:</b>
4.435 + * If the retrieved member is not public and
4.436 + * {@code lookc} is not present, then
4.437 + * {@link SecurityManager#checkPermission smgr.checkPermission}
4.438 + * with {@code RuntimePermission("accessDeclaredMembers")} is called.
4.439 + * <li><b>Step 3:</b>
4.440 + * If the retrieved member is not public,
4.441 + * and if {@code lookc} is not present,
4.442 + * and if {@code defc} and {@code refc} are different,
4.443 + * then {@link SecurityManager#checkPackageAccess
4.444 + * smgr.checkPackageAccess(defcPkg)} is called,
4.445 + * where {@code defcPkg} is the package of {@code defc}.
4.446 + * </ul>
4.447 + * Security checks are performed after other access checks have passed.
4.448 + * Therefore, the above rules presuppose a member that is public,
4.449 + * or else that is being accessed from a lookup class that has
4.450 + * rights to access the member.
4.451 + *
4.452 + * <h1><a name="callsens"></a>Caller sensitive methods</h1>
4.453 + * A small number of Java methods have a special property called caller sensitivity.
4.454 + * A <em>caller-sensitive</em> method can behave differently depending on the
4.455 + * identity of its immediate caller.
4.456 + * <p>
4.457 + * If a method handle for a caller-sensitive method is requested,
4.458 + * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
4.459 + * but they take account of the lookup class in a special way.
4.460 + * The resulting method handle behaves as if it were called
4.461 + * from an instruction contained in the lookup class,
4.462 + * so that the caller-sensitive method detects the lookup class.
4.463 + * (By contrast, the invoker of the method handle is disregarded.)
4.464 + * Thus, in the case of caller-sensitive methods,
4.465 + * different lookup classes may give rise to
4.466 + * differently behaving method handles.
4.467 + * <p>
4.468 + * In cases where the lookup object is
4.469 + * {@link MethodHandles#publicLookup() publicLookup()},
4.470 + * or some other lookup object without
4.471 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
4.472 + * the lookup class is disregarded.
4.473 + * In such cases, no caller-sensitive method handle can be created,
4.474 + * access is forbidden, and the lookup fails with an
4.475 + * {@code IllegalAccessException}.
4.476 + * <p style="font-size:smaller;">
4.477 + * <em>Discussion:</em>
4.478 + * For example, the caller-sensitive method
4.479 + * {@link java.lang.Class#forName(String) Class.forName(x)}
4.480 + * can return varying classes or throw varying exceptions,
4.481 + * depending on the class loader of the class that calls it.
4.482 + * A public lookup of {@code Class.forName} will fail, because
4.483 + * there is no reasonable way to determine its bytecode behavior.
4.484 + * <p style="font-size:smaller;">
4.485 + * If an application caches method handles for broad sharing,
4.486 + * it should use {@code publicLookup()} to create them.
4.487 + * If there is a lookup of {@code Class.forName}, it will fail,
4.488 + * and the application must take appropriate action in that case.
4.489 + * It may be that a later lookup, perhaps during the invocation of a
4.490 + * bootstrap method, can incorporate the specific identity
4.491 + * of the caller, making the method accessible.
4.492 + * <p style="font-size:smaller;">
4.493 + * The function {@code MethodHandles.lookup} is caller sensitive
4.494 + * so that there can be a secure foundation for lookups.
4.495 + * Nearly all other methods in the JSR 292 API rely on lookup
4.496 + * objects to check access requests.
4.497 + */
4.498 + public static final
4.499 + class Lookup {
4.500 + /** The class on behalf of whom the lookup is being performed. */
4.501 + private final Class<?> lookupClass;
4.502 +
4.503 + /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
4.504 + private final int allowedModes;
4.505 +
4.506 + /** A single-bit mask representing {@code public} access,
4.507 + * which may contribute to the result of {@link #lookupModes lookupModes}.
4.508 + * The value, {@code 0x01}, happens to be the same as the value of the
4.509 + * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
4.510 + */
4.511 + public static final int PUBLIC = Modifier.PUBLIC;
4.512 +
4.513 + /** A single-bit mask representing {@code private} access,
4.514 + * which may contribute to the result of {@link #lookupModes lookupModes}.
4.515 + * The value, {@code 0x02}, happens to be the same as the value of the
4.516 + * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
4.517 + */
4.518 + public static final int PRIVATE = Modifier.PRIVATE;
4.519 +
4.520 + /** A single-bit mask representing {@code protected} access,
4.521 + * which may contribute to the result of {@link #lookupModes lookupModes}.
4.522 + * The value, {@code 0x04}, happens to be the same as the value of the
4.523 + * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
4.524 + */
4.525 + public static final int PROTECTED = Modifier.PROTECTED;
4.526 +
4.527 + /** A single-bit mask representing {@code package} access (default access),
4.528 + * which may contribute to the result of {@link #lookupModes lookupModes}.
4.529 + * The value is {@code 0x08}, which does not correspond meaningfully to
4.530 + * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
4.531 + */
4.532 + public static final int PACKAGE = Modifier.STATIC;
4.533 +
4.534 + private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
4.535 + private static final int TRUSTED = -1;
4.536 +
4.537 + private static int fixmods(int mods) {
4.538 + mods &= (ALL_MODES - PACKAGE);
4.539 + return (mods != 0) ? mods : PACKAGE;
4.540 + }
4.541 +
4.542 + /** Tells which class is performing the lookup. It is this class against
4.543 + * which checks are performed for visibility and access permissions.
4.544 + * <p>
4.545 + * The class implies a maximum level of access permission,
4.546 + * but the permissions may be additionally limited by the bitmask
4.547 + * {@link #lookupModes lookupModes}, which controls whether non-public members
4.548 + * can be accessed.
4.549 + * @return the lookup class, on behalf of which this lookup object finds members
4.550 + */
4.551 + public Class<?> lookupClass() {
4.552 + return lookupClass;
4.553 + }
4.554 +
4.555 + // This is just for calling out to MethodHandleImpl.
4.556 + private Class<?> lookupClassOrNull() {
4.557 + return (allowedModes == TRUSTED) ? null : lookupClass;
4.558 + }
4.559 +
4.560 + /** Tells which access-protection classes of members this lookup object can produce.
4.561 + * The result is a bit-mask of the bits
4.562 + * {@linkplain #PUBLIC PUBLIC (0x01)},
4.563 + * {@linkplain #PRIVATE PRIVATE (0x02)},
4.564 + * {@linkplain #PROTECTED PROTECTED (0x04)},
4.565 + * and {@linkplain #PACKAGE PACKAGE (0x08)}.
4.566 + * <p>
4.567 + * A freshly-created lookup object
4.568 + * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
4.569 + * has all possible bits set, since the caller class can access all its own members.
4.570 + * A lookup object on a new lookup class
4.571 + * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
4.572 + * may have some mode bits set to zero.
4.573 + * The purpose of this is to restrict access via the new lookup object,
4.574 + * so that it can access only names which can be reached by the original
4.575 + * lookup object, and also by the new lookup class.
4.576 + * @return the lookup modes, which limit the kinds of access performed by this lookup object
4.577 + */
4.578 + public int lookupModes() {
4.579 + return allowedModes & ALL_MODES;
4.580 + }
4.581 +
4.582 + /** Embody the current class (the lookupClass) as a lookup class
4.583 + * for method handle creation.
4.584 + * Must be called by from a method in this package,
4.585 + * which in turn is called by a method not in this package.
4.586 + */
4.587 + Lookup(Class<?> lookupClass) {
4.588 + this(lookupClass, ALL_MODES);
4.589 + // make sure we haven't accidentally picked up a privileged class:
4.590 + }
4.591 +
4.592 + private Lookup(Class<?> lookupClass, int allowedModes) {
4.593 + this.lookupClass = lookupClass;
4.594 + this.allowedModes = allowedModes;
4.595 + }
4.596 +
4.597 + /**
4.598 + * Creates a lookup on the specified new lookup class.
4.599 + * The resulting object will report the specified
4.600 + * class as its own {@link #lookupClass lookupClass}.
4.601 + * <p>
4.602 + * However, the resulting {@code Lookup} object is guaranteed
4.603 + * to have no more access capabilities than the original.
4.604 + * In particular, access capabilities can be lost as follows:<ul>
4.605 + * <li>If the new lookup class differs from the old one,
4.606 + * protected members will not be accessible by virtue of inheritance.
4.607 + * (Protected members may continue to be accessible because of package sharing.)
4.608 + * <li>If the new lookup class is in a different package
4.609 + * than the old one, protected and default (package) members will not be accessible.
4.610 + * <li>If the new lookup class is not within the same package member
4.611 + * as the old one, private members will not be accessible.
4.612 + * <li>If the new lookup class is not accessible to the old lookup class,
4.613 + * then no members, not even public members, will be accessible.
4.614 + * (In all other cases, public members will continue to be accessible.)
4.615 + * </ul>
4.616 + *
4.617 + * @param requestedLookupClass the desired lookup class for the new lookup object
4.618 + * @return a lookup object which reports the desired lookup class
4.619 + * @throws NullPointerException if the argument is null
4.620 + */
4.621 + public Lookup in(Class<?> requestedLookupClass) {
4.622 + throw new IllegalStateException();
4.623 + }
4.624 +
4.625 + /** Version of lookup which is trusted minimally.
4.626 + * It can only be used to create method handles to
4.627 + * publicly accessible members.
4.628 + */
4.629 + static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
4.630 +
4.631 + /** Package-private version of lookup which is trusted. */
4.632 + static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
4.633 +
4.634 + /**
4.635 + * Displays the name of the class from which lookups are to be made.
4.636 + * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
4.637 + * If there are restrictions on the access permitted to this lookup,
4.638 + * this is indicated by adding a suffix to the class name, consisting
4.639 + * of a slash and a keyword. The keyword represents the strongest
4.640 + * allowed access, and is chosen as follows:
4.641 + * <ul>
4.642 + * <li>If no access is allowed, the suffix is "/noaccess".
4.643 + * <li>If only public access is allowed, the suffix is "/public".
4.644 + * <li>If only public and package access are allowed, the suffix is "/package".
4.645 + * <li>If only public, package, and private access are allowed, the suffix is "/private".
4.646 + * </ul>
4.647 + * If none of the above cases apply, it is the case that full
4.648 + * access (public, package, private, and protected) is allowed.
4.649 + * In this case, no suffix is added.
4.650 + * This is true only of an object obtained originally from
4.651 + * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
4.652 + * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
4.653 + * always have restricted access, and will display a suffix.
4.654 + * <p>
4.655 + * (It may seem strange that protected access should be
4.656 + * stronger than private access. Viewed independently from
4.657 + * package access, protected access is the first to be lost,
4.658 + * because it requires a direct subclass relationship between
4.659 + * caller and callee.)
4.660 + * @see #in
4.661 + */
4.662 + @Override
4.663 + public String toString() {
4.664 + String cname = lookupClass.getName();
4.665 + switch (allowedModes) {
4.666 + case 0: // no privileges
4.667 + return cname + "/noaccess";
4.668 + case PUBLIC:
4.669 + return cname + "/public";
4.670 + case PUBLIC|PACKAGE:
4.671 + return cname + "/package";
4.672 + case ALL_MODES & ~PROTECTED:
4.673 + return cname + "/private";
4.674 + case ALL_MODES:
4.675 + return cname;
4.676 + case TRUSTED:
4.677 + return "/trusted"; // internal only; not exported
4.678 + default: // Should not happen, but it's a bitfield...
4.679 + cname = cname + "/" + Integer.toHexString(allowedModes);
4.680 + assert(false) : cname;
4.681 + return cname;
4.682 + }
4.683 + }
4.684 +
4.685 + /**
4.686 + * Produces a method handle for a static method.
4.687 + * The type of the method handle will be that of the method.
4.688 + * (Since static methods do not take receivers, there is no
4.689 + * additional receiver argument inserted into the method handle type,
4.690 + * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
4.691 + * The method and all its argument types must be accessible to the lookup object.
4.692 + * <p>
4.693 + * The returned method handle will have
4.694 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.695 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
4.696 + * <p>
4.697 + * If the returned method handle is invoked, the method's class will
4.698 + * be initialized, if it has not already been initialized.
4.699 + * <p><b>Example:</b>
4.700 + * <blockquote><pre>{@code
4.701 +import static java.lang.invoke.MethodHandles.*;
4.702 +import static java.lang.invoke.MethodType.*;
4.703 +...
4.704 +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
4.705 + "asList", methodType(List.class, Object[].class));
4.706 +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
4.707 + * }</pre></blockquote>
4.708 + * @param refc the class from which the method is accessed
4.709 + * @param name the name of the method
4.710 + * @param type the type of the method
4.711 + * @return the desired method handle
4.712 + * @throws NoSuchMethodException if the method does not exist
4.713 + * @throws IllegalAccessException if access checking fails,
4.714 + * or if the method is not {@code static},
4.715 + * or if the method's variable arity modifier bit
4.716 + * is set and {@code asVarargsCollector} fails
4.717 + * @exception SecurityException if a security manager is present and it
4.718 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.719 + * @throws NullPointerException if any argument is null
4.720 + */
4.721 + public
4.722 + MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
4.723 + throw new IllegalStateException();
4.724 + }
4.725 +
4.726 + /**
4.727 + * Produces a method handle for a virtual method.
4.728 + * The type of the method handle will be that of the method,
4.729 + * with the receiver type (usually {@code refc}) prepended.
4.730 + * The method and all its argument types must be accessible to the lookup object.
4.731 + * <p>
4.732 + * When called, the handle will treat the first argument as a receiver
4.733 + * and dispatch on the receiver's type to determine which method
4.734 + * implementation to enter.
4.735 + * (The dispatching action is identical with that performed by an
4.736 + * {@code invokevirtual} or {@code invokeinterface} instruction.)
4.737 + * <p>
4.738 + * The first argument will be of type {@code refc} if the lookup
4.739 + * class has full privileges to access the member. Otherwise
4.740 + * the member must be {@code protected} and the first argument
4.741 + * will be restricted in type to the lookup class.
4.742 + * <p>
4.743 + * The returned method handle will have
4.744 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.745 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
4.746 + * <p>
4.747 + * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
4.748 + * instructions and method handles produced by {@code findVirtual},
4.749 + * if the class is {@code MethodHandle} and the name string is
4.750 + * {@code invokeExact} or {@code invoke}, the resulting
4.751 + * method handle is equivalent to one produced by
4.752 + * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
4.753 + * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
4.754 + * with the same {@code type} argument.
4.755 + *
4.756 + * <b>Example:</b>
4.757 + * <blockquote><pre>{@code
4.758 +import static java.lang.invoke.MethodHandles.*;
4.759 +import static java.lang.invoke.MethodType.*;
4.760 +...
4.761 +MethodHandle MH_concat = publicLookup().findVirtual(String.class,
4.762 + "concat", methodType(String.class, String.class));
4.763 +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
4.764 + "hashCode", methodType(int.class));
4.765 +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
4.766 + "hashCode", methodType(int.class));
4.767 +assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
4.768 +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
4.769 +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
4.770 +// interface method:
4.771 +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
4.772 + "subSequence", methodType(CharSequence.class, int.class, int.class));
4.773 +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
4.774 +// constructor "internal method" must be accessed differently:
4.775 +MethodType MT_newString = methodType(void.class); //()V for new String()
4.776 +try { assertEquals("impossible", lookup()
4.777 + .findVirtual(String.class, "<init>", MT_newString));
4.778 + } catch (NoSuchMethodException ex) { } // OK
4.779 +MethodHandle MH_newString = publicLookup()
4.780 + .findConstructor(String.class, MT_newString);
4.781 +assertEquals("", (String) MH_newString.invokeExact());
4.782 + * }</pre></blockquote>
4.783 + *
4.784 + * @param refc the class or interface from which the method is accessed
4.785 + * @param name the name of the method
4.786 + * @param type the type of the method, with the receiver argument omitted
4.787 + * @return the desired method handle
4.788 + * @throws NoSuchMethodException if the method does not exist
4.789 + * @throws IllegalAccessException if access checking fails,
4.790 + * or if the method is {@code static}
4.791 + * or if the method's variable arity modifier bit
4.792 + * is set and {@code asVarargsCollector} fails
4.793 + * @exception SecurityException if a security manager is present and it
4.794 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.795 + * @throws NullPointerException if any argument is null
4.796 + */
4.797 + public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
4.798 + throw new IllegalStateException();
4.799 + }
4.800 +
4.801 + /**
4.802 + * Produces a method handle which creates an object and initializes it, using
4.803 + * the constructor of the specified type.
4.804 + * The parameter types of the method handle will be those of the constructor,
4.805 + * while the return type will be a reference to the constructor's class.
4.806 + * The constructor and all its argument types must be accessible to the lookup object.
4.807 + * <p>
4.808 + * The requested type must have a return type of {@code void}.
4.809 + * (This is consistent with the JVM's treatment of constructor type descriptors.)
4.810 + * <p>
4.811 + * The returned method handle will have
4.812 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.813 + * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
4.814 + * <p>
4.815 + * If the returned method handle is invoked, the constructor's class will
4.816 + * be initialized, if it has not already been initialized.
4.817 + * <p><b>Example:</b>
4.818 + * <blockquote><pre>{@code
4.819 +import static java.lang.invoke.MethodHandles.*;
4.820 +import static java.lang.invoke.MethodType.*;
4.821 +...
4.822 +MethodHandle MH_newArrayList = publicLookup().findConstructor(
4.823 + ArrayList.class, methodType(void.class, Collection.class));
4.824 +Collection orig = Arrays.asList("x", "y");
4.825 +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
4.826 +assert(orig != copy);
4.827 +assertEquals(orig, copy);
4.828 +// a variable-arity constructor:
4.829 +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
4.830 + ProcessBuilder.class, methodType(void.class, String[].class));
4.831 +ProcessBuilder pb = (ProcessBuilder)
4.832 + MH_newProcessBuilder.invoke("x", "y", "z");
4.833 +assertEquals("[x, y, z]", pb.command().toString());
4.834 + * }</pre></blockquote>
4.835 + * @param refc the class or interface from which the method is accessed
4.836 + * @param type the type of the method, with the receiver argument omitted, and a void return type
4.837 + * @return the desired method handle
4.838 + * @throws NoSuchMethodException if the constructor does not exist
4.839 + * @throws IllegalAccessException if access checking fails
4.840 + * or if the method's variable arity modifier bit
4.841 + * is set and {@code asVarargsCollector} fails
4.842 + * @exception SecurityException if a security manager is present and it
4.843 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.844 + * @throws NullPointerException if any argument is null
4.845 + */
4.846 + public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
4.847 + throw new IllegalStateException();
4.848 + }
4.849 +
4.850 + /**
4.851 + * Produces an early-bound method handle for a virtual method.
4.852 + * It will bypass checks for overriding methods on the receiver,
4.853 + * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
4.854 + * instruction from within the explicitly specified {@code specialCaller}.
4.855 + * The type of the method handle will be that of the method,
4.856 + * with a suitably restricted receiver type prepended.
4.857 + * (The receiver type will be {@code specialCaller} or a subtype.)
4.858 + * The method and all its argument types must be accessible
4.859 + * to the lookup object.
4.860 + * <p>
4.861 + * Before method resolution,
4.862 + * if the explicitly specified caller class is not identical with the
4.863 + * lookup class, or if this lookup object does not have
4.864 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>
4.865 + * privileges, the access fails.
4.866 + * <p>
4.867 + * The returned method handle will have
4.868 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.869 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
4.870 + * <p style="font-size:smaller;">
4.871 + * <em>(Note: JVM internal methods named {@code "<init>"} are not visible to this API,
4.872 + * even though the {@code invokespecial} instruction can refer to them
4.873 + * in special circumstances. Use {@link #findConstructor findConstructor}
4.874 + * to access instance initialization methods in a safe manner.)</em>
4.875 + * <p><b>Example:</b>
4.876 + * <blockquote><pre>{@code
4.877 +import static java.lang.invoke.MethodHandles.*;
4.878 +import static java.lang.invoke.MethodType.*;
4.879 +...
4.880 +static class Listie extends ArrayList {
4.881 + public String toString() { return "[wee Listie]"; }
4.882 + static Lookup lookup() { return MethodHandles.lookup(); }
4.883 +}
4.884 +...
4.885 +// no access to constructor via invokeSpecial:
4.886 +MethodHandle MH_newListie = Listie.lookup()
4.887 + .findConstructor(Listie.class, methodType(void.class));
4.888 +Listie l = (Listie) MH_newListie.invokeExact();
4.889 +try { assertEquals("impossible", Listie.lookup().findSpecial(
4.890 + Listie.class, "<init>", methodType(void.class), Listie.class));
4.891 + } catch (NoSuchMethodException ex) { } // OK
4.892 +// access to super and self methods via invokeSpecial:
4.893 +MethodHandle MH_super = Listie.lookup().findSpecial(
4.894 + ArrayList.class, "toString" , methodType(String.class), Listie.class);
4.895 +MethodHandle MH_this = Listie.lookup().findSpecial(
4.896 + Listie.class, "toString" , methodType(String.class), Listie.class);
4.897 +MethodHandle MH_duper = Listie.lookup().findSpecial(
4.898 + Object.class, "toString" , methodType(String.class), Listie.class);
4.899 +assertEquals("[]", (String) MH_super.invokeExact(l));
4.900 +assertEquals(""+l, (String) MH_this.invokeExact(l));
4.901 +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
4.902 +try { assertEquals("inaccessible", Listie.lookup().findSpecial(
4.903 + String.class, "toString", methodType(String.class), Listie.class));
4.904 + } catch (IllegalAccessException ex) { } // OK
4.905 +Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
4.906 +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
4.907 + * }</pre></blockquote>
4.908 + *
4.909 + * @param refc the class or interface from which the method is accessed
4.910 + * @param name the name of the method (which must not be "<init>")
4.911 + * @param type the type of the method, with the receiver argument omitted
4.912 + * @param specialCaller the proposed calling class to perform the {@code invokespecial}
4.913 + * @return the desired method handle
4.914 + * @throws NoSuchMethodException if the method does not exist
4.915 + * @throws IllegalAccessException if access checking fails
4.916 + * or if the method's variable arity modifier bit
4.917 + * is set and {@code asVarargsCollector} fails
4.918 + * @exception SecurityException if a security manager is present and it
4.919 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.920 + * @throws NullPointerException if any argument is null
4.921 + */
4.922 + public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
4.923 + Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
4.924 + throw new IllegalStateException();
4.925 + }
4.926 +
4.927 + /**
4.928 + * Produces a method handle giving read access to a non-static field.
4.929 + * The type of the method handle will have a return type of the field's
4.930 + * value type.
4.931 + * The method handle's single argument will be the instance containing
4.932 + * the field.
4.933 + * Access checking is performed immediately on behalf of the lookup class.
4.934 + * @param refc the class or interface from which the method is accessed
4.935 + * @param name the field's name
4.936 + * @param type the field's type
4.937 + * @return a method handle which can load values from the field
4.938 + * @throws NoSuchFieldException if the field does not exist
4.939 + * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
4.940 + * @exception SecurityException if a security manager is present and it
4.941 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.942 + * @throws NullPointerException if any argument is null
4.943 + */
4.944 + public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
4.945 + throw new IllegalStateException();
4.946 + }
4.947 +
4.948 + /**
4.949 + * Produces a method handle giving write access to a non-static field.
4.950 + * The type of the method handle will have a void return type.
4.951 + * The method handle will take two arguments, the instance containing
4.952 + * the field, and the value to be stored.
4.953 + * The second argument will be of the field's value type.
4.954 + * Access checking is performed immediately on behalf of the lookup class.
4.955 + * @param refc the class or interface from which the method is accessed
4.956 + * @param name the field's name
4.957 + * @param type the field's type
4.958 + * @return a method handle which can store values into the field
4.959 + * @throws NoSuchFieldException if the field does not exist
4.960 + * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
4.961 + * @exception SecurityException if a security manager is present and it
4.962 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.963 + * @throws NullPointerException if any argument is null
4.964 + */
4.965 + public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
4.966 + throw new IllegalStateException();
4.967 + }
4.968 +
4.969 + /**
4.970 + * Produces a method handle giving read access to a static field.
4.971 + * The type of the method handle will have a return type of the field's
4.972 + * value type.
4.973 + * The method handle will take no arguments.
4.974 + * Access checking is performed immediately on behalf of the lookup class.
4.975 + * <p>
4.976 + * If the returned method handle is invoked, the field's class will
4.977 + * be initialized, if it has not already been initialized.
4.978 + * @param refc the class or interface from which the method is accessed
4.979 + * @param name the field's name
4.980 + * @param type the field's type
4.981 + * @return a method handle which can load values from the field
4.982 + * @throws NoSuchFieldException if the field does not exist
4.983 + * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
4.984 + * @exception SecurityException if a security manager is present and it
4.985 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.986 + * @throws NullPointerException if any argument is null
4.987 + */
4.988 + public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
4.989 + throw new IllegalStateException();
4.990 + }
4.991 +
4.992 + /**
4.993 + * Produces a method handle giving write access to a static field.
4.994 + * The type of the method handle will have a void return type.
4.995 + * The method handle will take a single
4.996 + * argument, of the field's value type, the value to be stored.
4.997 + * Access checking is performed immediately on behalf of the lookup class.
4.998 + * <p>
4.999 + * If the returned method handle is invoked, the field's class will
4.1000 + * be initialized, if it has not already been initialized.
4.1001 + * @param refc the class or interface from which the method is accessed
4.1002 + * @param name the field's name
4.1003 + * @param type the field's type
4.1004 + * @return a method handle which can store values into the field
4.1005 + * @throws NoSuchFieldException if the field does not exist
4.1006 + * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
4.1007 + * @exception SecurityException if a security manager is present and it
4.1008 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.1009 + * @throws NullPointerException if any argument is null
4.1010 + */
4.1011 + public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws IllegalAccessException {
4.1012 + throw new IllegalStateException();
4.1013 + }
4.1014 +
4.1015 + /**
4.1016 + * Produces an early-bound method handle for a non-static method.
4.1017 + * The receiver must have a supertype {@code defc} in which a method
4.1018 + * of the given name and type is accessible to the lookup class.
4.1019 + * The method and all its argument types must be accessible to the lookup object.
4.1020 + * The type of the method handle will be that of the method,
4.1021 + * without any insertion of an additional receiver parameter.
4.1022 + * The given receiver will be bound into the method handle,
4.1023 + * so that every call to the method handle will invoke the
4.1024 + * requested method on the given receiver.
4.1025 + * <p>
4.1026 + * The returned method handle will have
4.1027 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.1028 + * the method's variable arity modifier bit ({@code 0x0080}) is set
4.1029 + * <em>and</em> the trailing array argument is not the only argument.
4.1030 + * (If the trailing array argument is the only argument,
4.1031 + * the given receiver value will be bound to it.)
4.1032 + * <p>
4.1033 + * This is equivalent to the following code:
4.1034 + * <blockquote><pre>{@code
4.1035 +import static java.lang.invoke.MethodHandles.*;
4.1036 +import static java.lang.invoke.MethodType.*;
4.1037 +...
4.1038 +MethodHandle mh0 = lookup().findVirtual(defc, name, type);
4.1039 +MethodHandle mh1 = mh0.bindTo(receiver);
4.1040 +MethodType mt1 = mh1.type();
4.1041 +if (mh0.isVarargsCollector())
4.1042 + mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
4.1043 +return mh1;
4.1044 + * }</pre></blockquote>
4.1045 + * where {@code defc} is either {@code receiver.getClass()} or a super
4.1046 + * type of that class, in which the requested method is accessible
4.1047 + * to the lookup class.
4.1048 + * (Note that {@code bindTo} does not preserve variable arity.)
4.1049 + * @param receiver the object from which the method is accessed
4.1050 + * @param name the name of the method
4.1051 + * @param type the type of the method, with the receiver argument omitted
4.1052 + * @return the desired method handle
4.1053 + * @throws NoSuchMethodException if the method does not exist
4.1054 + * @throws IllegalAccessException if access checking fails
4.1055 + * or if the method's variable arity modifier bit
4.1056 + * is set and {@code asVarargsCollector} fails
4.1057 + * @exception SecurityException if a security manager is present and it
4.1058 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.1059 + * @throws NullPointerException if any argument is null
4.1060 + * @see MethodHandle#bindTo
4.1061 + * @see #findVirtual
4.1062 + */
4.1063 + public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
4.1064 + throw new IllegalStateException();
4.1065 + }
4.1066 +
4.1067 + /**
4.1068 + * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
4.1069 + * to <i>m</i>, if the lookup class has permission.
4.1070 + * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
4.1071 + * If <i>m</i> is virtual, overriding is respected on every call.
4.1072 + * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
4.1073 + * The type of the method handle will be that of the method,
4.1074 + * with the receiver type prepended (but only if it is non-static).
4.1075 + * If the method's {@code accessible} flag is not set,
4.1076 + * access checking is performed immediately on behalf of the lookup class.
4.1077 + * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
4.1078 + * <p>
4.1079 + * The returned method handle will have
4.1080 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.1081 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
4.1082 + * <p>
4.1083 + * If <i>m</i> is static, and
4.1084 + * if the returned method handle is invoked, the method's class will
4.1085 + * be initialized, if it has not already been initialized.
4.1086 + * @param m the reflected method
4.1087 + * @return a method handle which can invoke the reflected method
4.1088 + * @throws IllegalAccessException if access checking fails
4.1089 + * or if the method's variable arity modifier bit
4.1090 + * is set and {@code asVarargsCollector} fails
4.1091 + * @throws NullPointerException if the argument is null
4.1092 + */
4.1093 + public MethodHandle unreflect(Method m) throws IllegalAccessException {
4.1094 + throw new IllegalStateException();
4.1095 + }
4.1096 +
4.1097 + /**
4.1098 + * Produces a method handle for a reflected method.
4.1099 + * It will bypass checks for overriding methods on the receiver,
4.1100 + * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
4.1101 + * instruction from within the explicitly specified {@code specialCaller}.
4.1102 + * The type of the method handle will be that of the method,
4.1103 + * with a suitably restricted receiver type prepended.
4.1104 + * (The receiver type will be {@code specialCaller} or a subtype.)
4.1105 + * If the method's {@code accessible} flag is not set,
4.1106 + * access checking is performed immediately on behalf of the lookup class,
4.1107 + * as if {@code invokespecial} instruction were being linked.
4.1108 + * <p>
4.1109 + * Before method resolution,
4.1110 + * if the explicitly specified caller class is not identical with the
4.1111 + * lookup class, or if this lookup object does not have
4.1112 + * <a href="MethodHandles.Lookup.html#privacc">private access</a>
4.1113 + * privileges, the access fails.
4.1114 + * <p>
4.1115 + * The returned method handle will have
4.1116 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.1117 + * the method's variable arity modifier bit ({@code 0x0080}) is set.
4.1118 + * @param m the reflected method
4.1119 + * @param specialCaller the class nominally calling the method
4.1120 + * @return a method handle which can invoke the reflected method
4.1121 + * @throws IllegalAccessException if access checking fails
4.1122 + * or if the method's variable arity modifier bit
4.1123 + * is set and {@code asVarargsCollector} fails
4.1124 + * @throws NullPointerException if any argument is null
4.1125 + */
4.1126 + public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
4.1127 + throw new IllegalStateException();
4.1128 + }
4.1129 +
4.1130 + /**
4.1131 + * Produces a method handle for a reflected constructor.
4.1132 + * The type of the method handle will be that of the constructor,
4.1133 + * with the return type changed to the declaring class.
4.1134 + * The method handle will perform a {@code newInstance} operation,
4.1135 + * creating a new instance of the constructor's class on the
4.1136 + * arguments passed to the method handle.
4.1137 + * <p>
4.1138 + * If the constructor's {@code accessible} flag is not set,
4.1139 + * access checking is performed immediately on behalf of the lookup class.
4.1140 + * <p>
4.1141 + * The returned method handle will have
4.1142 + * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
4.1143 + * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
4.1144 + * <p>
4.1145 + * If the returned method handle is invoked, the constructor's class will
4.1146 + * be initialized, if it has not already been initialized.
4.1147 + * @param c the reflected constructor
4.1148 + * @return a method handle which can invoke the reflected constructor
4.1149 + * @throws IllegalAccessException if access checking fails
4.1150 + * or if the method's variable arity modifier bit
4.1151 + * is set and {@code asVarargsCollector} fails
4.1152 + * @throws NullPointerException if the argument is null
4.1153 + */
4.1154 + public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
4.1155 + throw new IllegalStateException();
4.1156 + }
4.1157 +
4.1158 + /**
4.1159 + * Produces a method handle giving read access to a reflected field.
4.1160 + * The type of the method handle will have a return type of the field's
4.1161 + * value type.
4.1162 + * If the field is static, the method handle will take no arguments.
4.1163 + * Otherwise, its single argument will be the instance containing
4.1164 + * the field.
4.1165 + * If the field's {@code accessible} flag is not set,
4.1166 + * access checking is performed immediately on behalf of the lookup class.
4.1167 + * <p>
4.1168 + * If the field is static, and
4.1169 + * if the returned method handle is invoked, the field's class will
4.1170 + * be initialized, if it has not already been initialized.
4.1171 + * @param f the reflected field
4.1172 + * @return a method handle which can load values from the reflected field
4.1173 + * @throws IllegalAccessException if access checking fails
4.1174 + * @throws NullPointerException if the argument is null
4.1175 + */
4.1176 + public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
4.1177 + throw new IllegalStateException();
4.1178 + }
4.1179 +
4.1180 + /**
4.1181 + * Produces a method handle giving write access to a reflected field.
4.1182 + * The type of the method handle will have a void return type.
4.1183 + * If the field is static, the method handle will take a single
4.1184 + * argument, of the field's value type, the value to be stored.
4.1185 + * Otherwise, the two arguments will be the instance containing
4.1186 + * the field, and the value to be stored.
4.1187 + * If the field's {@code accessible} flag is not set,
4.1188 + * access checking is performed immediately on behalf of the lookup class.
4.1189 + * <p>
4.1190 + * If the field is static, and
4.1191 + * if the returned method handle is invoked, the field's class will
4.1192 + * be initialized, if it has not already been initialized.
4.1193 + * @param f the reflected field
4.1194 + * @return a method handle which can store values into the reflected field
4.1195 + * @throws IllegalAccessException if access checking fails
4.1196 + * @throws NullPointerException if the argument is null
4.1197 + */
4.1198 + public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
4.1199 + throw new IllegalStateException();
4.1200 + }
4.1201 +
4.1202 + /**
4.1203 + * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
4.1204 + * created by this lookup object or a similar one.
4.1205 + * Security and access checks are performed to ensure that this lookup object
4.1206 + * is capable of reproducing the target method handle.
4.1207 + * This means that the cracking may fail if target is a direct method handle
4.1208 + * but was created by an unrelated lookup object.
4.1209 + * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
4.1210 + * and was created by a lookup object for a different class.
4.1211 + * @param target a direct method handle to crack into symbolic reference components
4.1212 + * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
4.1213 + * @exception SecurityException if a security manager is present and it
4.1214 + * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
4.1215 + * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
4.1216 + * @exception NullPointerException if the target is {@code null}
4.1217 + * @see MethodHandleInfo
4.1218 + * @since 1.8
4.1219 + */
4.1220 +// public MethodHandleInfo revealDirect(MethodHandle target) {
4.1221 +// throw new IllegalStateException();
4.1222 +// }
4.1223 + }
4.1224 +
4.1225 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodType.java Sun Sep 14 19:27:44 2014 +0200
5.3 @@ -0,0 +1,846 @@
5.4 +/*
5.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.7 + *
5.8 + * This code is free software; you can redistribute it and/or modify it
5.9 + * under the terms of the GNU General Public License version 2 only, as
5.10 + * published by the Free Software Foundation. Oracle designates this
5.11 + * particular file as subject to the "Classpath" exception as provided
5.12 + * by Oracle in the LICENSE file that accompanied this code.
5.13 + *
5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.17 + * version 2 for more details (a copy is included in the LICENSE file that
5.18 + * accompanied this code).
5.19 + *
5.20 + * You should have received a copy of the GNU General Public License version
5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.23 + *
5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.25 + * or visit www.oracle.com if you need additional information or have any
5.26 + * questions.
5.27 + */
5.28 +
5.29 +package java.lang.invoke;
5.30 +
5.31 +import java.lang.ref.WeakReference;
5.32 +import java.lang.ref.Reference;
5.33 +import java.lang.ref.ReferenceQueue;
5.34 +import java.util.Arrays;
5.35 +import java.util.Collections;
5.36 +import java.util.List;
5.37 +import java.util.Objects;
5.38 +import java.util.concurrent.ConcurrentMap;
5.39 +import java.util.concurrent.ConcurrentHashMap;
5.40 +
5.41 +/**
5.42 + * A method type represents the arguments and return type accepted and
5.43 + * returned by a method handle, or the arguments and return type passed
5.44 + * and expected by a method handle caller. Method types must be properly
5.45 + * matched between a method handle and all its callers,
5.46 + * and the JVM's operations enforce this matching at, specifically
5.47 + * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
5.48 + * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
5.49 + * of {@code invokedynamic} instructions.
5.50 + * <p>
5.51 + * The structure is a return type accompanied by any number of parameter types.
5.52 + * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
5.53 + * (For ease of exposition, we treat {@code void} as if it were a type.
5.54 + * In fact, it denotes the absence of a return type.)
5.55 + * <p>
5.56 + * All instances of {@code MethodType} are immutable.
5.57 + * Two instances are completely interchangeable if they compare equal.
5.58 + * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
5.59 + * <p>
5.60 + * This type can be created only by factory methods.
5.61 + * All factory methods may cache values, though caching is not guaranteed.
5.62 + * Some factory methods are static, while others are virtual methods which
5.63 + * modify precursor method types, e.g., by changing a selected parameter.
5.64 + * <p>
5.65 + * Factory methods which operate on groups of parameter types
5.66 + * are systematically presented in two versions, so that both Java arrays and
5.67 + * Java lists can be used to work with groups of parameter types.
5.68 + * The query methods {@code parameterArray} and {@code parameterList}
5.69 + * also provide a choice between arrays and lists.
5.70 + * <p>
5.71 + * {@code MethodType} objects are sometimes derived from bytecode instructions
5.72 + * such as {@code invokedynamic}, specifically from the type descriptor strings associated
5.73 + * with the instructions in a class file's constant pool.
5.74 + * <p>
5.75 + * Like classes and strings, method types can also be represented directly
5.76 + * in a class file's constant pool as constants.
5.77 + * A method type may be loaded by an {@code ldc} instruction which refers
5.78 + * to a suitable {@code CONSTANT_MethodType} constant pool entry.
5.79 + * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
5.80 + * (For full details on method type constants,
5.81 + * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
5.82 + * <p>
5.83 + * When the JVM materializes a {@code MethodType} from a descriptor string,
5.84 + * all classes named in the descriptor must be accessible, and will be loaded.
5.85 + * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
5.86 + * This loading may occur at any time before the {@code MethodType} object is first derived.
5.87 + * @author John Rose, JSR 292 EG
5.88 + */
5.89 +public final
5.90 +class MethodType implements java.io.Serializable {
5.91 + private static final long serialVersionUID = 292L; // {rtype, {ptype...}}
5.92 +
5.93 + // The rtype and ptypes fields define the structural identity of the method type:
5.94 + private final Class<?> rtype;
5.95 + private final Class<?>[] ptypes;
5.96 +
5.97 + /**
5.98 + * Check the given parameters for validity and store them into the final fields.
5.99 + */
5.100 + private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
5.101 + this.rtype = rtype;
5.102 + // defensively copy the array passed in by the user
5.103 + this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
5.104 + }
5.105 +
5.106 + /**
5.107 + * Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
5.108 + * Does not check the given parameters for validity, and must be discarded after it is used as a searching key.
5.109 + * The parameters are reversed for this constructor, so that is is not accidentally used.
5.110 + */
5.111 + private MethodType(Class<?>[] ptypes, Class<?> rtype) {
5.112 + this.rtype = rtype;
5.113 + this.ptypes = ptypes;
5.114 + }
5.115 +
5.116 + /** This number, mandated by the JVM spec as 255,
5.117 + * is the maximum number of <em>slots</em>
5.118 + * that any Java method can receive in its argument list.
5.119 + * It limits both JVM signatures and method type objects.
5.120 + * The longest possible invocation will look like
5.121 + * {@code staticMethod(arg1, arg2, ..., arg255)} or
5.122 + * {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
5.123 + */
5.124 + /*non-public*/ static final int MAX_JVM_ARITY = 255; // this is mandated by the JVM spec.
5.125 +
5.126 + /** This number is the maximum arity of a method handle, 254.
5.127 + * It is derived from the absolute JVM-imposed arity by subtracting one,
5.128 + * which is the slot occupied by the method handle itself at the
5.129 + * beginning of the argument list used to invoke the method handle.
5.130 + * The longest possible invocation will look like
5.131 + * {@code mh.invoke(arg1, arg2, ..., arg254)}.
5.132 + */
5.133 + // Issue: Should we allow MH.invokeWithArguments to go to the full 255?
5.134 + /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1; // deduct one for mh receiver
5.135 +
5.136 + /** This number is the maximum arity of a method handle invoker, 253.
5.137 + * It is derived from the absolute JVM-imposed arity by subtracting two,
5.138 + * which are the slots occupied by invoke method handle, and the
5.139 + * target method handle, which are both at the beginning of the argument
5.140 + * list used to invoke the target method handle.
5.141 + * The longest possible invocation will look like
5.142 + * {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
5.143 + */
5.144 + /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1; // deduct one more for invoker
5.145 +
5.146 + private static void checkRtype(Class<?> rtype) {
5.147 + Objects.requireNonNull(rtype);
5.148 + }
5.149 +
5.150 + static final ConcurrentWeakInternSet<MethodType> internTable = new ConcurrentWeakInternSet<>();
5.151 +
5.152 + static final Class<?>[] NO_PTYPES = {};
5.153 +
5.154 + /**
5.155 + * Finds or creates an instance of the given method type.
5.156 + * @param rtype the return type
5.157 + * @param ptypes the parameter types
5.158 + * @return a method type with the given components
5.159 + * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
5.160 + * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
5.161 + */
5.162 + public static
5.163 + MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
5.164 + return makeImpl(rtype, ptypes, false);
5.165 + }
5.166 +
5.167 + /**
5.168 + * Finds or creates a method type with the given components.
5.169 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.170 + * @param rtype the return type
5.171 + * @param ptypes the parameter types
5.172 + * @return a method type with the given components
5.173 + * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
5.174 + * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
5.175 + */
5.176 + public static
5.177 + MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
5.178 + boolean notrust = false; // random List impl. could return evil ptypes array
5.179 + return makeImpl(rtype, listToArray(ptypes), notrust);
5.180 + }
5.181 +
5.182 + private static Class<?>[] listToArray(List<Class<?>> ptypes) {
5.183 + return ptypes.toArray(NO_PTYPES);
5.184 + }
5.185 +
5.186 + /**
5.187 + * Finds or creates a method type with the given components.
5.188 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.189 + * The leading parameter type is prepended to the remaining array.
5.190 + * @param rtype the return type
5.191 + * @param ptype0 the first parameter type
5.192 + * @param ptypes the remaining parameter types
5.193 + * @return a method type with the given components
5.194 + * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
5.195 + * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
5.196 + */
5.197 + public static
5.198 + MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
5.199 + Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
5.200 + ptypes1[0] = ptype0;
5.201 + System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
5.202 + return makeImpl(rtype, ptypes1, true);
5.203 + }
5.204 +
5.205 + /**
5.206 + * Finds or creates a method type with the given components.
5.207 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.208 + * The resulting method has no parameter types.
5.209 + * @param rtype the return type
5.210 + * @return a method type with the given return value
5.211 + * @throws NullPointerException if {@code rtype} is null
5.212 + */
5.213 + public static
5.214 + MethodType methodType(Class<?> rtype) {
5.215 + return makeImpl(rtype, NO_PTYPES, true);
5.216 + }
5.217 +
5.218 + /**
5.219 + * Finds or creates a method type with the given components.
5.220 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.221 + * The resulting method has the single given parameter type.
5.222 + * @param rtype the return type
5.223 + * @param ptype0 the parameter type
5.224 + * @return a method type with the given return value and parameter type
5.225 + * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
5.226 + * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
5.227 + */
5.228 + public static
5.229 + MethodType methodType(Class<?> rtype, Class<?> ptype0) {
5.230 + return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
5.231 + }
5.232 +
5.233 + /**
5.234 + * Finds or creates a method type with the given components.
5.235 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.236 + * The resulting method has the same parameter types as {@code ptypes},
5.237 + * and the specified return type.
5.238 + * @param rtype the return type
5.239 + * @param ptypes the method type which supplies the parameter types
5.240 + * @return a method type with the given components
5.241 + * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
5.242 + */
5.243 + public static
5.244 + MethodType methodType(Class<?> rtype, MethodType ptypes) {
5.245 + return makeImpl(rtype, ptypes.ptypes, true);
5.246 + }
5.247 +
5.248 + /**
5.249 + * Sole factory method to find or create an interned method type.
5.250 + * @param rtype desired return type
5.251 + * @param ptypes desired parameter types
5.252 + * @param trusted whether the ptypes can be used without cloning
5.253 + * @return the unique method type of the desired structure
5.254 + */
5.255 + /*trusted*/ static
5.256 + MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
5.257 + throw new IllegalStateException();
5.258 + }
5.259 + private static final MethodType[] objectOnlyTypes = new MethodType[20];
5.260 +
5.261 + /**
5.262 + * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
5.263 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.264 + * All parameters and the return type will be {@code Object},
5.265 + * except the final array parameter if any, which will be {@code Object[]}.
5.266 + * @param objectArgCount number of parameters (excluding the final array parameter if any)
5.267 + * @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
5.268 + * @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
5.269 + * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray} is true)
5.270 + * @see #genericMethodType(int)
5.271 + */
5.272 + public static
5.273 + MethodType genericMethodType(int objectArgCount, boolean finalArray) {
5.274 + throw new IllegalStateException();
5.275 + }
5.276 +
5.277 + /**
5.278 + * Finds or creates a method type whose components are all {@code Object}.
5.279 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.280 + * All parameters and the return type will be Object.
5.281 + * @param objectArgCount number of parameters
5.282 + * @return a generally applicable method type, for all calls of the given argument count
5.283 + * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
5.284 + * @see #genericMethodType(int, boolean)
5.285 + */
5.286 + public static
5.287 + MethodType genericMethodType(int objectArgCount) {
5.288 + return genericMethodType(objectArgCount, false);
5.289 + }
5.290 +
5.291 + /**
5.292 + * Finds or creates a method type with a single different parameter type.
5.293 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.294 + * @param num the index (zero-based) of the parameter type to change
5.295 + * @param nptype a new parameter type to replace the old one with
5.296 + * @return the same type, except with the selected parameter changed
5.297 + * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
5.298 + * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
5.299 + * @throws NullPointerException if {@code nptype} is null
5.300 + */
5.301 + public MethodType changeParameterType(int num, Class<?> nptype) {
5.302 + throw new IllegalStateException();
5.303 + }
5.304 +
5.305 + /**
5.306 + * Finds or creates a method type with additional parameter types.
5.307 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.308 + * @param num the position (zero-based) of the inserted parameter type(s)
5.309 + * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
5.310 + * @return the same type, except with the selected parameter(s) inserted
5.311 + * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
5.312 + * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
5.313 + * or if the resulting method type would have more than 255 parameter slots
5.314 + * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
5.315 + */
5.316 + public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
5.317 + throw new IllegalStateException();
5.318 + }
5.319 +
5.320 + /**
5.321 + * Finds or creates a method type with additional parameter types.
5.322 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.323 + * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
5.324 + * @return the same type, except with the selected parameter(s) appended
5.325 + * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
5.326 + * or if the resulting method type would have more than 255 parameter slots
5.327 + * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
5.328 + */
5.329 + public MethodType appendParameterTypes(Class<?>... ptypesToInsert) {
5.330 + return insertParameterTypes(parameterCount(), ptypesToInsert);
5.331 + }
5.332 +
5.333 + /**
5.334 + * Finds or creates a method type with additional parameter types.
5.335 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.336 + * @param num the position (zero-based) of the inserted parameter type(s)
5.337 + * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
5.338 + * @return the same type, except with the selected parameter(s) inserted
5.339 + * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
5.340 + * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
5.341 + * or if the resulting method type would have more than 255 parameter slots
5.342 + * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
5.343 + */
5.344 + public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
5.345 + return insertParameterTypes(num, listToArray(ptypesToInsert));
5.346 + }
5.347 +
5.348 + /**
5.349 + * Finds or creates a method type with additional parameter types.
5.350 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.351 + * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
5.352 + * @return the same type, except with the selected parameter(s) appended
5.353 + * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
5.354 + * or if the resulting method type would have more than 255 parameter slots
5.355 + * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
5.356 + */
5.357 + public MethodType appendParameterTypes(List<Class<?>> ptypesToInsert) {
5.358 + return insertParameterTypes(parameterCount(), ptypesToInsert);
5.359 + }
5.360 +
5.361 + /**
5.362 + * Finds or creates a method type with modified parameter types.
5.363 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.364 + * @param start the position (zero-based) of the first replaced parameter type(s)
5.365 + * @param end the position (zero-based) after the last replaced parameter type(s)
5.366 + * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
5.367 + * @return the same type, except with the selected parameter(s) replaced
5.368 + * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
5.369 + * or if {@code end} is negative or greater than {@code parameterCount()}
5.370 + * or if {@code start} is greater than {@code end}
5.371 + * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
5.372 + * or if the resulting method type would have more than 255 parameter slots
5.373 + * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
5.374 + */
5.375 + /*non-public*/ MethodType replaceParameterTypes(int start, int end, Class<?>... ptypesToInsert) {
5.376 + throw new IllegalStateException();
5.377 + }
5.378 +
5.379 + /**
5.380 + * Finds or creates a method type with some parameter types omitted.
5.381 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.382 + * @param start the index (zero-based) of the first parameter type to remove
5.383 + * @param end the index (greater than {@code start}) of the first parameter type after not to remove
5.384 + * @return the same type, except with the selected parameter(s) removed
5.385 + * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
5.386 + * or if {@code end} is negative or greater than {@code parameterCount()}
5.387 + * or if {@code start} is greater than {@code end}
5.388 + */
5.389 + public MethodType dropParameterTypes(int start, int end) {
5.390 + throw new IllegalStateException();
5.391 + }
5.392 +
5.393 + /**
5.394 + * Finds or creates a method type with a different return type.
5.395 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.396 + * @param nrtype a return parameter type to replace the old one with
5.397 + * @return the same type, except with the return type change
5.398 + * @throws NullPointerException if {@code nrtype} is null
5.399 + */
5.400 + public MethodType changeReturnType(Class<?> nrtype) {
5.401 + throw new IllegalStateException();
5.402 + }
5.403 +
5.404 + /**
5.405 + * Reports if this type contains a primitive argument or return value.
5.406 + * The return type {@code void} counts as a primitive.
5.407 + * @return true if any of the types are primitives
5.408 + */
5.409 + public boolean hasPrimitives() {
5.410 + throw new IllegalStateException();
5.411 + }
5.412 +
5.413 + /**
5.414 + * Reports if this type contains a wrapper argument or return value.
5.415 + * Wrappers are types which box primitive values, such as {@link Integer}.
5.416 + * The reference type {@code java.lang.Void} counts as a wrapper,
5.417 + * if it occurs as a return type.
5.418 + * @return true if any of the types are wrappers
5.419 + */
5.420 + public boolean hasWrappers() {
5.421 + return unwrap() != this;
5.422 + }
5.423 +
5.424 + /**
5.425 + * Erases all reference types to {@code Object}.
5.426 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.427 + * All primitive types (including {@code void}) will remain unchanged.
5.428 + * @return a version of the original type with all reference types replaced
5.429 + */
5.430 + public MethodType erase() {
5.431 + throw new IllegalStateException();
5.432 + }
5.433 +
5.434 + /**
5.435 + * Erases all reference types to {@code Object}, and all subword types to {@code int}.
5.436 + * This is the reduced type polymorphism used by private methods
5.437 + * such as {@link MethodHandle#invokeBasic invokeBasic}.
5.438 + * @return a version of the original type with all reference and subword types replaced
5.439 + */
5.440 + /*non-public*/ MethodType basicType() {
5.441 + throw new IllegalStateException();
5.442 + }
5.443 +
5.444 + /**
5.445 + * @return a version of the original type with MethodHandle prepended as the first argument
5.446 + */
5.447 + /*non-public*/ MethodType invokerType() {
5.448 + throw new IllegalStateException();
5.449 + }
5.450 +
5.451 + /**
5.452 + * Converts all types, both reference and primitive, to {@code Object}.
5.453 + * Convenience method for {@link #genericMethodType(int) genericMethodType}.
5.454 + * The expression {@code type.wrap().erase()} produces the same value
5.455 + * as {@code type.generic()}.
5.456 + * @return a version of the original type with all types replaced
5.457 + */
5.458 + public MethodType generic() {
5.459 + return genericMethodType(parameterCount());
5.460 + }
5.461 +
5.462 + /**
5.463 + * Converts all primitive types to their corresponding wrapper types.
5.464 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.465 + * All reference types (including wrapper types) will remain unchanged.
5.466 + * A {@code void} return type is changed to the type {@code java.lang.Void}.
5.467 + * The expression {@code type.wrap().erase()} produces the same value
5.468 + * as {@code type.generic()}.
5.469 + * @return a version of the original type with all primitive types replaced
5.470 + */
5.471 + public MethodType wrap() {
5.472 + return hasPrimitives() ? wrapWithPrims(this) : this;
5.473 + }
5.474 +
5.475 + /**
5.476 + * Converts all wrapper types to their corresponding primitive types.
5.477 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.478 + * All primitive types (including {@code void}) will remain unchanged.
5.479 + * A return type of {@code java.lang.Void} is changed to {@code void}.
5.480 + * @return a version of the original type with all wrapper types replaced
5.481 + */
5.482 + public MethodType unwrap() {
5.483 + MethodType noprims = !hasPrimitives() ? this : wrapWithPrims(this);
5.484 + return unwrapWithNoPrims(noprims);
5.485 + }
5.486 +
5.487 + private static MethodType wrapWithPrims(MethodType pt) {
5.488 + throw new IllegalStateException();
5.489 + }
5.490 +
5.491 + private static MethodType unwrapWithNoPrims(MethodType wt) {
5.492 + throw new IllegalStateException();
5.493 + }
5.494 +
5.495 + /**
5.496 + * Returns the parameter type at the specified index, within this method type.
5.497 + * @param num the index (zero-based) of the desired parameter type
5.498 + * @return the selected parameter type
5.499 + * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
5.500 + */
5.501 + public Class<?> parameterType(int num) {
5.502 + return ptypes[num];
5.503 + }
5.504 + /**
5.505 + * Returns the number of parameter types in this method type.
5.506 + * @return the number of parameter types
5.507 + */
5.508 + public int parameterCount() {
5.509 + return ptypes.length;
5.510 + }
5.511 + /**
5.512 + * Returns the return type of this method type.
5.513 + * @return the return type
5.514 + */
5.515 + public Class<?> returnType() {
5.516 + return rtype;
5.517 + }
5.518 +
5.519 + /**
5.520 + * Presents the parameter types as a list (a convenience method).
5.521 + * The list will be immutable.
5.522 + * @return the parameter types (as an immutable list)
5.523 + */
5.524 + public List<Class<?>> parameterList() {
5.525 + return Collections.unmodifiableList(Arrays.asList(ptypes));
5.526 + }
5.527 +
5.528 + /*non-public*/ Class<?> lastParameterType() {
5.529 + int len = ptypes.length;
5.530 + return len == 0 ? void.class : ptypes[len-1];
5.531 + }
5.532 +
5.533 + /**
5.534 + * Presents the parameter types as an array (a convenience method).
5.535 + * Changes to the array will not result in changes to the type.
5.536 + * @return the parameter types (as a fresh copy if necessary)
5.537 + */
5.538 + public Class<?>[] parameterArray() {
5.539 + return ptypes.clone();
5.540 + }
5.541 +
5.542 + /**
5.543 + * Compares the specified object with this type for equality.
5.544 + * That is, it returns <tt>true</tt> if and only if the specified object
5.545 + * is also a method type with exactly the same parameters and return type.
5.546 + * @param x object to compare
5.547 + * @see Object#equals(Object)
5.548 + */
5.549 + @Override
5.550 + public boolean equals(Object x) {
5.551 + return this == x || x instanceof MethodType && equals((MethodType)x);
5.552 + }
5.553 +
5.554 + private boolean equals(MethodType that) {
5.555 + return this.rtype == that.rtype
5.556 + && Arrays.equals(this.ptypes, that.ptypes);
5.557 + }
5.558 +
5.559 + /**
5.560 + * Returns the hash code value for this method type.
5.561 + * It is defined to be the same as the hashcode of a List
5.562 + * whose elements are the return type followed by the
5.563 + * parameter types.
5.564 + * @return the hash code value for this method type
5.565 + * @see Object#hashCode()
5.566 + * @see #equals(Object)
5.567 + * @see List#hashCode()
5.568 + */
5.569 + @Override
5.570 + public int hashCode() {
5.571 + int hashCode = 31 + rtype.hashCode();
5.572 + for (Class<?> ptype : ptypes)
5.573 + hashCode = 31*hashCode + ptype.hashCode();
5.574 + return hashCode;
5.575 + }
5.576 +
5.577 + /**
5.578 + * Returns a string representation of the method type,
5.579 + * of the form {@code "(PT0,PT1...)RT"}.
5.580 + * The string representation of a method type is a
5.581 + * parenthesis enclosed, comma separated list of type names,
5.582 + * followed immediately by the return type.
5.583 + * <p>
5.584 + * Each type is represented by its
5.585 + * {@link java.lang.Class#getSimpleName simple name}.
5.586 + */
5.587 + @Override
5.588 + public String toString() {
5.589 + StringBuilder sb = new StringBuilder();
5.590 + sb.append("(");
5.591 + for (int i = 0; i < ptypes.length; i++) {
5.592 + if (i > 0) sb.append(",");
5.593 + sb.append(ptypes[i].getSimpleName());
5.594 + }
5.595 + sb.append(")");
5.596 + sb.append(rtype.getSimpleName());
5.597 + return sb.toString();
5.598 + }
5.599 +
5.600 +
5.601 + /**
5.602 + * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
5.603 + * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
5.604 + * Any class or interface name embedded in the descriptor string
5.605 + * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
5.606 + * on the given loader (or if it is null, on the system class loader).
5.607 + * <p>
5.608 + * Note that it is possible to encounter method types which cannot be
5.609 + * constructed by this method, because their component types are
5.610 + * not all reachable from a common class loader.
5.611 + * <p>
5.612 + * This method is included for the benefit of applications that must
5.613 + * generate bytecodes that process method handles and {@code invokedynamic}.
5.614 + * @param descriptor a bytecode-level type descriptor string "(T...)T"
5.615 + * @param loader the class loader in which to look up the types
5.616 + * @return a method type matching the bytecode-level type descriptor
5.617 + * @throws NullPointerException if the string is null
5.618 + * @throws IllegalArgumentException if the string is not well-formed
5.619 + * @throws TypeNotPresentException if a named type cannot be found
5.620 + */
5.621 + public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
5.622 + throws IllegalArgumentException
5.623 + {
5.624 + throw new IllegalStateException();
5.625 + }
5.626 +
5.627 + /**
5.628 + * Produces a bytecode descriptor representation of the method type.
5.629 + * <p>
5.630 + * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
5.631 + * Two distinct classes which share a common name but have different class loaders
5.632 + * will appear identical when viewed within descriptor strings.
5.633 + * <p>
5.634 + * This method is included for the benefit of applications that must
5.635 + * generate bytecodes that process method handles and {@code invokedynamic}.
5.636 + * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
5.637 + * because the latter requires a suitable class loader argument.
5.638 + * @return the bytecode type descriptor representation
5.639 + */
5.640 + public String toMethodDescriptorString() {
5.641 + throw new IllegalStateException();
5.642 + }
5.643 +
5.644 + /// Serialization.
5.645 +
5.646 + /**
5.647 + * There are no serializable fields for {@code MethodType}.
5.648 + */
5.649 + private static final java.io.ObjectStreamField[] serialPersistentFields = { };
5.650 +
5.651 +// /**
5.652 +// * Save the {@code MethodType} instance to a stream.
5.653 +// *
5.654 +// * @serialData
5.655 +// * For portability, the serialized format does not refer to named fields.
5.656 +// * Instead, the return type and parameter type arrays are written directly
5.657 +// * from the {@code writeObject} method, using two calls to {@code s.writeObject}
5.658 +// * as follows:
5.659 +// * <blockquote><pre>{@code
5.660 +//s.writeObject(this.returnType());
5.661 +//s.writeObject(this.parameterArray());
5.662 +// * }</pre></blockquote>
5.663 +// * <p>
5.664 +// * The deserialized field values are checked as if they were
5.665 +// * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
5.666 +// * For example, null values, or {@code void} parameter types,
5.667 +// * will lead to exceptions during deserialization.
5.668 +// * @param s the stream to write the object to
5.669 +// * @throws java.io.IOException if there is a problem writing the object
5.670 +// */
5.671 +// private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
5.672 +// s.defaultWriteObject(); // requires serialPersistentFields to be an empty array
5.673 +// s.writeObject(returnType());
5.674 +// s.writeObject(parameterArray());
5.675 +// }
5.676 +//
5.677 +// /**
5.678 +// * Reconstitute the {@code MethodType} instance from a stream (that is,
5.679 +// * deserialize it).
5.680 +// * This instance is a scratch object with bogus final fields.
5.681 +// * It provides the parameters to the factory method called by
5.682 +// * {@link #readResolve readResolve}.
5.683 +// * After that call it is discarded.
5.684 +// * @param s the stream to read the object from
5.685 +// * @throws java.io.IOException if there is a problem reading the object
5.686 +// * @throws ClassNotFoundException if one of the component classes cannot be resolved
5.687 +// * @see #MethodType()
5.688 +// * @see #readResolve
5.689 +// * @see #writeObject
5.690 +// */
5.691 +// private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
5.692 +// s.defaultReadObject(); // requires serialPersistentFields to be an empty array
5.693 +//
5.694 +// Class<?> returnType = (Class<?>) s.readObject();
5.695 +// Class<?>[] parameterArray = (Class<?>[]) s.readObject();
5.696 +//
5.697 +// // Probably this object will never escape, but let's check
5.698 +// // the field values now, just to be sure.
5.699 +// checkRtype(returnType);
5.700 +// checkPtypes(parameterArray);
5.701 +//
5.702 +// parameterArray = parameterArray.clone(); // make sure it is unshared
5.703 +// MethodType_init(returnType, parameterArray);
5.704 +// }
5.705 +
5.706 + /**
5.707 + * For serialization only.
5.708 + * Sets the final fields to null, pending {@code Unsafe.putObject}.
5.709 + */
5.710 + private MethodType() {
5.711 + this.rtype = null;
5.712 + this.ptypes = null;
5.713 + }
5.714 +// private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
5.715 +// // In order to communicate these values to readResolve, we must
5.716 +// // store them into the implementation-specific final fields.
5.717 +// checkRtype(rtype);
5.718 +// checkPtypes(ptypes);
5.719 +// UNSAFE.putObject(this, rtypeOffset, rtype);
5.720 +// UNSAFE.putObject(this, ptypesOffset, ptypes);
5.721 +// }
5.722 +
5.723 + // Support for resetting final fields while deserializing
5.724 +// private static final long rtypeOffset, ptypesOffset;
5.725 +// static {
5.726 +// try {
5.727 +// rtypeOffset = UNSAFE.objectFieldOffset
5.728 +// (MethodType.class.getDeclaredField("rtype"));
5.729 +// ptypesOffset = UNSAFE.objectFieldOffset
5.730 +// (MethodType.class.getDeclaredField("ptypes"));
5.731 +// } catch (Exception ex) {
5.732 +// throw new Error(ex);
5.733 +// }
5.734 +// }
5.735 +
5.736 + /**
5.737 + * Resolves and initializes a {@code MethodType} object
5.738 + * after serialization.
5.739 + * @return the fully initialized {@code MethodType} object
5.740 + */
5.741 + private Object readResolve() {
5.742 + // Do not use a trusted path for deserialization:
5.743 + //return makeImpl(rtype, ptypes, true);
5.744 + // Verify all operands, and make sure ptypes is unshared:
5.745 + return methodType(rtype, ptypes);
5.746 + }
5.747 +
5.748 + /**
5.749 + * Simple implementation of weak concurrent intern set.
5.750 + *
5.751 + * @param <T> interned type
5.752 + */
5.753 + private static class ConcurrentWeakInternSet<T> {
5.754 +
5.755 + private final ConcurrentMap<WeakEntry<T>, WeakEntry<T>> map;
5.756 + private final ReferenceQueue<T> stale;
5.757 +
5.758 + public ConcurrentWeakInternSet() {
5.759 + this.map = new ConcurrentHashMap<>();
5.760 + this.stale = new ReferenceQueue<>();
5.761 + }
5.762 +
5.763 + /**
5.764 + * Get the existing interned element.
5.765 + * This method returns null if no element is interned.
5.766 + *
5.767 + * @param elem element to look up
5.768 + * @return the interned element
5.769 + */
5.770 + public T get(T elem) {
5.771 + if (elem == null) throw new NullPointerException();
5.772 + expungeStaleElements();
5.773 +
5.774 + WeakEntry<T> value = map.get(new WeakEntry<>(elem));
5.775 + if (value != null) {
5.776 + T res = value.get();
5.777 + if (res != null) {
5.778 + return res;
5.779 + }
5.780 + }
5.781 + return null;
5.782 + }
5.783 +
5.784 + /**
5.785 + * Interns the element.
5.786 + * Always returns non-null element, matching the one in the intern set.
5.787 + * Under the race against another add(), it can return <i>different</i>
5.788 + * element, if another thread beats us to interning it.
5.789 + *
5.790 + * @param elem element to add
5.791 + * @return element that was actually added
5.792 + */
5.793 + public T add(T elem) {
5.794 + if (elem == null) throw new NullPointerException();
5.795 +
5.796 + // Playing double race here, and so spinloop is required.
5.797 + // First race is with two concurrent updaters.
5.798 + // Second race is with GC purging weak ref under our feet.
5.799 + // Hopefully, we almost always end up with a single pass.
5.800 + T interned;
5.801 + WeakEntry<T> e = new WeakEntry<>(elem, stale);
5.802 + do {
5.803 + expungeStaleElements();
5.804 + WeakEntry<T> exist = map.putIfAbsent(e, e);
5.805 + interned = (exist == null) ? elem : exist.get();
5.806 + } while (interned == null);
5.807 + return interned;
5.808 + }
5.809 +
5.810 + private void expungeStaleElements() {
5.811 + Reference<? extends T> reference;
5.812 + while ((reference = stale.poll()) != null) {
5.813 + map.remove(reference);
5.814 + }
5.815 + }
5.816 +
5.817 + private static class WeakEntry<T> extends WeakReference<T> {
5.818 +
5.819 + public final int hashcode;
5.820 +
5.821 + public WeakEntry(T key, ReferenceQueue<T> queue) {
5.822 + super(key, queue);
5.823 + hashcode = key.hashCode();
5.824 + }
5.825 +
5.826 + public WeakEntry(T key) {
5.827 + super(key);
5.828 + hashcode = key.hashCode();
5.829 + }
5.830 +
5.831 + @Override
5.832 + public boolean equals(Object obj) {
5.833 + if (obj instanceof WeakEntry) {
5.834 + Object that = ((WeakEntry) obj).get();
5.835 + Object mine = get();
5.836 + return (that == null || mine == null) ? (this == obj) : mine.equals(that);
5.837 + }
5.838 + return false;
5.839 + }
5.840 +
5.841 + @Override
5.842 + public int hashCode() {
5.843 + return hashcode;
5.844 + }
5.845 +
5.846 + }
5.847 + }
5.848 +
5.849 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/SerializedLambda.java Sun Sep 14 19:27:44 2014 +0200
6.3 @@ -0,0 +1,257 @@
6.4 +/*
6.5 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.7 + *
6.8 + * This code is free software; you can redistribute it and/or modify it
6.9 + * under the terms of the GNU General Public License version 2 only, as
6.10 + * published by the Free Software Foundation. Oracle designates this
6.11 + * particular file as subject to the "Classpath" exception as provided
6.12 + * by Oracle in the LICENSE file that accompanied this code.
6.13 + *
6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.17 + * version 2 for more details (a copy is included in the LICENSE file that
6.18 + * accompanied this code).
6.19 + *
6.20 + * You should have received a copy of the GNU General Public License version
6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.23 + *
6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.25 + * or visit www.oracle.com if you need additional information or have any
6.26 + * questions.
6.27 + */
6.28 +package java.lang.invoke;
6.29 +
6.30 +import java.io.Serializable;
6.31 +import java.lang.reflect.Method;
6.32 +import java.security.AccessController;
6.33 +import java.security.PrivilegedActionException;
6.34 +import java.security.PrivilegedExceptionAction;
6.35 +import java.util.Objects;
6.36 +
6.37 +/**
6.38 + * Serialized form of a lambda expression. The properties of this class
6.39 + * represent the information that is present at the lambda factory site, including
6.40 + * static metafactory arguments such as the identity of the primary functional
6.41 + * interface method and the identity of the implementation method, as well as
6.42 + * dynamic metafactory arguments such as values captured from the lexical scope
6.43 + * at the time of lambda capture.
6.44 + *
6.45 + * <p>Implementors of serializable lambdas, such as compilers or language
6.46 + * runtime libraries, are expected to ensure that instances deserialize properly.
6.47 + * One means to do so is to ensure that the {@code writeReplace} method returns
6.48 + * an instance of {@code SerializedLambda}, rather than allowing default
6.49 + * serialization to proceed.
6.50 + *
6.51 + * <p>{@code SerializedLambda} has a {@code readResolve} method that looks for
6.52 + * a (possibly private) static method called
6.53 + * {@code $deserializeLambda$(SerializedLambda)} in the capturing class, invokes
6.54 + * that with itself as the first argument, and returns the result. Lambda classes
6.55 + * implementing {@code $deserializeLambda$} are responsible for validating
6.56 + * that the properties of the {@code SerializedLambda} are consistent with a
6.57 + * lambda actually captured by that class.
6.58 + *
6.59 + * @see LambdaMetafactory
6.60 + */
6.61 +public final class SerializedLambda implements Serializable {
6.62 + private static final long serialVersionUID = 8025925345765570181L;
6.63 + private final Class<?> capturingClass;
6.64 + private final String functionalInterfaceClass;
6.65 + private final String functionalInterfaceMethodName;
6.66 + private final String functionalInterfaceMethodSignature;
6.67 + private final String implClass;
6.68 + private final String implMethodName;
6.69 + private final String implMethodSignature;
6.70 + private final int implMethodKind;
6.71 + private final String instantiatedMethodType;
6.72 + private final Object[] capturedArgs;
6.73 +
6.74 + /**
6.75 + * Create a {@code SerializedLambda} from the low-level information present
6.76 + * at the lambda factory site.
6.77 + *
6.78 + * @param capturingClass The class in which the lambda expression appears
6.79 + * @param functionalInterfaceClass Name, in slash-delimited form, of static
6.80 + * type of the returned lambda object
6.81 + * @param functionalInterfaceMethodName Name of the functional interface
6.82 + * method for the present at the
6.83 + * lambda factory site
6.84 + * @param functionalInterfaceMethodSignature Signature of the functional
6.85 + * interface method present at
6.86 + * the lambda factory site
6.87 + * @param implMethodKind Method handle kind for the implementation method
6.88 + * @param implClass Name, in slash-delimited form, for the class holding
6.89 + * the implementation method
6.90 + * @param implMethodName Name of the implementation method
6.91 + * @param implMethodSignature Signature of the implementation method
6.92 + * @param instantiatedMethodType The signature of the primary functional
6.93 + * interface method after type variables
6.94 + * are substituted with their instantiation
6.95 + * from the capture site
6.96 + * @param capturedArgs The dynamic arguments to the lambda factory site,
6.97 + * which represent variables captured by
6.98 + * the lambda
6.99 + */
6.100 + public SerializedLambda(Class<?> capturingClass,
6.101 + String functionalInterfaceClass,
6.102 + String functionalInterfaceMethodName,
6.103 + String functionalInterfaceMethodSignature,
6.104 + int implMethodKind,
6.105 + String implClass,
6.106 + String implMethodName,
6.107 + String implMethodSignature,
6.108 + String instantiatedMethodType,
6.109 + Object[] capturedArgs) {
6.110 + this.capturingClass = capturingClass;
6.111 + this.functionalInterfaceClass = functionalInterfaceClass;
6.112 + this.functionalInterfaceMethodName = functionalInterfaceMethodName;
6.113 + this.functionalInterfaceMethodSignature = functionalInterfaceMethodSignature;
6.114 + this.implMethodKind = implMethodKind;
6.115 + this.implClass = implClass;
6.116 + this.implMethodName = implMethodName;
6.117 + this.implMethodSignature = implMethodSignature;
6.118 + this.instantiatedMethodType = instantiatedMethodType;
6.119 + this.capturedArgs = Objects.requireNonNull(capturedArgs).clone();
6.120 + }
6.121 +
6.122 + /**
6.123 + * Get the name of the class that captured this lambda.
6.124 + * @return the name of the class that captured this lambda
6.125 + */
6.126 + public String getCapturingClass() {
6.127 + return capturingClass.getName().replace('.', '/');
6.128 + }
6.129 +
6.130 + /**
6.131 + * Get the name of the invoked type to which this
6.132 + * lambda has been converted
6.133 + * @return the name of the functional interface class to which
6.134 + * this lambda has been converted
6.135 + */
6.136 + public String getFunctionalInterfaceClass() {
6.137 + return functionalInterfaceClass;
6.138 + }
6.139 +
6.140 + /**
6.141 + * Get the name of the primary method for the functional interface
6.142 + * to which this lambda has been converted.
6.143 + * @return the name of the primary methods of the functional interface
6.144 + */
6.145 + public String getFunctionalInterfaceMethodName() {
6.146 + return functionalInterfaceMethodName;
6.147 + }
6.148 +
6.149 + /**
6.150 + * Get the signature of the primary method for the functional
6.151 + * interface to which this lambda has been converted.
6.152 + * @return the signature of the primary method of the functional
6.153 + * interface
6.154 + */
6.155 + public String getFunctionalInterfaceMethodSignature() {
6.156 + return functionalInterfaceMethodSignature;
6.157 + }
6.158 +
6.159 + /**
6.160 + * Get the name of the class containing the implementation
6.161 + * method.
6.162 + * @return the name of the class containing the implementation
6.163 + * method
6.164 + */
6.165 + public String getImplClass() {
6.166 + return implClass;
6.167 + }
6.168 +
6.169 + /**
6.170 + * Get the name of the implementation method.
6.171 + * @return the name of the implementation method
6.172 + */
6.173 + public String getImplMethodName() {
6.174 + return implMethodName;
6.175 + }
6.176 +
6.177 + /**
6.178 + * Get the signature of the implementation method.
6.179 + * @return the signature of the implementation method
6.180 + */
6.181 + public String getImplMethodSignature() {
6.182 + return implMethodSignature;
6.183 + }
6.184 +
6.185 + /**
6.186 + * Get the method handle kind (see {@link MethodHandleInfo}) of
6.187 + * the implementation method.
6.188 + * @return the method handle kind of the implementation method
6.189 + */
6.190 + public int getImplMethodKind() {
6.191 + return implMethodKind;
6.192 + }
6.193 +
6.194 + /**
6.195 + * Get the signature of the primary functional interface method
6.196 + * after type variables are substituted with their instantiation
6.197 + * from the capture site.
6.198 + * @return the signature of the primary functional interface method
6.199 + * after type variable processing
6.200 + */
6.201 + public final String getInstantiatedMethodType() {
6.202 + return instantiatedMethodType;
6.203 + }
6.204 +
6.205 + /**
6.206 + * Get the count of dynamic arguments to the lambda capture site.
6.207 + * @return the count of dynamic arguments to the lambda capture site
6.208 + */
6.209 + public int getCapturedArgCount() {
6.210 + return capturedArgs.length;
6.211 + }
6.212 +
6.213 + /**
6.214 + * Get a dynamic argument to the lambda capture site.
6.215 + * @param i the argument to capture
6.216 + * @return a dynamic argument to the lambda capture site
6.217 + */
6.218 + public Object getCapturedArg(int i) {
6.219 + return capturedArgs[i];
6.220 + }
6.221 +
6.222 + private Object readResolve() throws ReflectiveOperationException {
6.223 + try {
6.224 + Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
6.225 + @Override
6.226 + public Method run() throws Exception {
6.227 + Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
6.228 + m.setAccessible(true);
6.229 + return m;
6.230 + }
6.231 + });
6.232 +
6.233 + return deserialize.invoke(null, this);
6.234 + }
6.235 + catch (PrivilegedActionException e) {
6.236 + Exception cause = e.getException();
6.237 + if (cause instanceof ReflectiveOperationException)
6.238 + throw (ReflectiveOperationException) cause;
6.239 + else if (cause instanceof RuntimeException)
6.240 + throw (RuntimeException) cause;
6.241 + else
6.242 + throw new RuntimeException("Exception in SerializedLambda.readResolve", e);
6.243 + }
6.244 + }
6.245 +
6.246 + @Override
6.247 + public String toString() {
6.248 + return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " +
6.249 + "%s=%s %s.%s:%s, %s=%s, %s=%d]",
6.250 + "capturingClass", capturingClass,
6.251 + "functionalInterfaceMethod", functionalInterfaceClass,
6.252 + functionalInterfaceMethodName,
6.253 + functionalInterfaceMethodSignature,
6.254 + "implementation",
6.255 + null,
6.256 + implClass, implMethodName, implMethodSignature,
6.257 + "instantiatedMethodType", instantiatedMethodType,
6.258 + "numCaptured", capturedArgs.length);
6.259 + }
6.260 +}
7.1 --- a/rt/vm8/pom.xml Sat Sep 13 22:29:13 2014 +0200
7.2 +++ b/rt/vm8/pom.xml Sun Sep 14 19:27:44 2014 +0200
7.3 @@ -18,6 +18,9 @@
7.4 <configuration>
7.5 <source>1.8</source>
7.6 <target>1.8</target>
7.7 + <compilerArguments>
7.8 + <bootclasspath>netbeans.ignore.jdk.bootclasspath</bootclasspath>
7.9 + </compilerArguments>
7.10 </configuration>
7.11 </plugin>
7.12 <plugin>
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/LambdasSuper.java Sun Sep 14 19:27:44 2014 +0200
8.3 @@ -0,0 +1,28 @@
8.4 +/**
8.5 + * Back 2 Browser Bytecode Translator
8.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
8.7 + *
8.8 + * This program is free software: you can redistribute it and/or modify
8.9 + * it under the terms of the GNU General Public License as published by
8.10 + * the Free Software Foundation, version 2 of the License.
8.11 + *
8.12 + * This program is distributed in the hope that it will be useful,
8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.15 + * GNU General Public License for more details.
8.16 + *
8.17 + * You should have received a copy of the GNU General Public License
8.18 + * along with this program. Look for COPYING file in the top folder.
8.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
8.20 + */
8.21 +package org.apidesign.bck2brwsr.vm8;
8.22 +
8.23 +/**
8.24 + *
8.25 + * @author Jaroslav Tulach
8.26 + */
8.27 +class LambdasSuper {
8.28 + String inheritedMethod() {
8.29 + return "superclass version";
8.30 + }
8.31 +}
9.1 --- a/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/LambdasTest.java Sat Sep 13 22:29:13 2014 +0200
9.2 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/LambdasTest.java Sun Sep 14 19:27:44 2014 +0200
9.3 @@ -17,6 +17,10 @@
9.4 */
9.5 package org.apidesign.bck2brwsr.vm8;
9.6
9.7 +import java.util.ArrayList;
9.8 +import java.util.Arrays;
9.9 +import java.util.List;
9.10 +import java.util.concurrent.Callable;
9.11 import org.apidesign.bck2brwsr.vmtest.Compare;
9.12 import org.apidesign.bck2brwsr.vmtest.VMTest;
9.13 import org.testng.annotations.Factory;
9.14 @@ -25,10 +29,140 @@
9.15 *
9.16 * @author Jaroslav Tulach <jtulach@netbeans.org>
9.17 */
9.18 -public class LambdasTest {
9.19 +public class LambdasTest extends LambdasSuper {
9.20 @Compare public String StringverifyJSTime() throws Exception {
9.21 return Lambdas.compound();
9.22 }
9.23 +
9.24 + @Compare
9.25 + public int canCallLambda() {
9.26 + int[] arr = {0};
9.27 + Runnable incr = () -> {
9.28 + arr[0]++;
9.29 + };
9.30 + incr.run();
9.31 + return arr[0];
9.32 + }
9.33 +
9.34 + @Compare
9.35 + public String lambdaReturnsString() throws Exception {
9.36 + Callable<String> lambda = () -> "Hello World!";
9.37 + return lambda.call();
9.38 + }
9.39 +
9.40 + private interface Convertor<P, R> {
9.41 +
9.42 + public R convert(P value);
9.43 + }
9.44 +
9.45 + @Compare
9.46 + public int convertToLength() {
9.47 + Convertor<String, Integer> lambda = (String s) -> s.getBytes().length;
9.48 + return lambda.convert("buu");
9.49 + }
9.50 +
9.51 + private int meaningOfWorld = 0;
9.52 +
9.53 + @Compare
9.54 + public int accessToInstanceVar() {
9.55 + Runnable lambda = () -> {
9.56 + meaningOfWorld = 42;
9.57 + };
9.58 + lambda.run();
9.59 + return meaningOfWorld;
9.60 + }
9.61 +
9.62 + @Compare
9.63 + public int localMeaningOfWorld() {
9.64 + int[] meansOfWorld = new int[1];
9.65 + Runnable lambda = () -> {
9.66 + meansOfWorld[0] = 42;
9.67 + };
9.68 + lambda.run();
9.69 + return meansOfWorld[0];
9.70 + }
9.71 +
9.72 + @Compare
9.73 + public int useLocalVars() throws Exception {
9.74 + boolean bool = true;
9.75 + byte b = 2;
9.76 + short s = 3;
9.77 + int i = 4;
9.78 + long l = 5;
9.79 + float f = 6;
9.80 + double d = 7;
9.81 + char c = 8;
9.82 + Callable<Integer> lambda = () -> (int) ((bool ? 1 : 0) + b + s + i + l + f + d + c);
9.83 + return lambda.call();
9.84 + }
9.85 +
9.86 + @Compare
9.87 + public String callVirtualMethod() throws Exception {
9.88 + String foo = "foo";
9.89 + Callable<String> ref = foo::toUpperCase;
9.90 + return ref.call();
9.91 + }
9.92 +
9.93 + @Compare
9.94 + public int callInterfaceMethod() throws Exception {
9.95 + List<String> foos = Arrays.asList("foo");
9.96 + Callable<Integer> ref = foos::size;
9.97 + return ref.call();
9.98 + }
9.99 +
9.100 + @Compare
9.101 + public long callStaticMethod() throws Exception {
9.102 + long expected = System.currentTimeMillis();
9.103 + Callable<Long> ref = System::currentTimeMillis;
9.104 + return ref.call() & ~0xffff;
9.105 + }
9.106 +
9.107 + @Compare
9.108 + public String callConstructor() throws Exception {
9.109 + Callable<List<String>> ref = ArrayList<String>::new;
9.110 + return ref.call().toString();
9.111 + }
9.112 +
9.113 + @Compare
9.114 + public String superMethodOverridenByThis() throws Exception {
9.115 + Callable<String> ref = super::inheritedMethod;
9.116 + return ref.call();
9.117 + }
9.118 +
9.119 + @Override
9.120 + String inheritedMethod() {
9.121 + return "overridden version";
9.122 + }
9.123 +
9.124 + @Compare
9.125 + public String referencePrivateClassMethod() throws Exception {
9.126 + StringBuilder sb = new StringBuilder();
9.127 +
9.128 + Callable<String> ref1 = LambdasTest::privateClassMethod;
9.129 + sb.append(ref1.call());
9.130 +
9.131 + Callable<String> ref2 = this::privateInstanceMethod;
9.132 + sb.append("\n").append(ref2.call());
9.133 +
9.134 + // Normal method calls should still work after our magic
9.135 + // of making them them accessible from the lambda classes.
9.136 + sb.append("\n").append(privateClassMethod());
9.137 + sb.append("\n").append(privateInstanceMethod());
9.138 +
9.139 + return sb.toString();
9.140 + }
9.141 +
9.142 + private String privateInstanceMethod() {
9.143 + return "foo";
9.144 + }
9.145 +
9.146 + private static String privateClassMethod() {
9.147 + return "foo";
9.148 + }
9.149 +
9.150 + private String unrelatedPrivateMethod() {
9.151 + return "foo";
9.152 + }
9.153
9.154 @Factory public static Object[] create() {
9.155 return VMTest.create(LambdasTest.class);