MethodHandle.java 32.6 KB
Newer Older
1
/*
2
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 4 5 6
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Oracle designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Oracle in the LICENSE file that accompanied this code.
10 11 12 13 14 15 16 17 18 19 20
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
21 22 23
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
24 25 26 27 28 29 30 31 32
 */

package java.dyn;

//import sun.dyn.*;

import sun.dyn.Access;
import sun.dyn.MethodHandleImpl;

33 34 35
import static java.dyn.MethodHandles.invokers;  // package-private API
import static sun.dyn.MemberName.newIllegalArgumentException;  // utility

36
/**
37 38
 * A method handle is a typed, directly executable reference to a method,
 * constructor, field, or similar low-level operation, with optional
39
 * transformations of arguments or return values.
40 41 42 43 44 45 46 47 48 49 50
 * These transformations are quite general, and include such patterns as
 * {@linkplain #asType conversion},
 * {@linkplain #bindTo insertion},
 * {@linkplain java.dyn.MethodHandles#dropArguments deletion},
 * and {@linkplain java.dyn.MethodHandles#filterArguments substitution}.
 * <p>
 * <em>Note: The super-class of MethodHandle is Object.
 *     Any other super-class visible in the Reference Implementation
 *     will be removed before the Proposed Final Draft.
 *     Also, the final version will not include any public or
 *     protected constructors.</em>
51 52 53
 * <p>
 * Method handles are strongly typed according to signature.
 * They are not distinguished by method name or enclosing class.
54
 * A method handle must be invoked under a signature which matches
55
 * the method handle's own {@linkplain MethodType method type}.
56
 * <p>
57
 * Every method handle reports its type via the {@link #type type} accessor.
58
 * The structure of this type is a series of classes, one of which is
59
 * the return type of the method (or {@code void.class} if none).
60 61
 * <p>
 * Every method handle appears as an object containing a method named
62
 * {@link #invokeExact invokeExact}, whose signature exactly matches
63
 * the method handle's type.
64
 * A Java method call expression, which compiles to an
65
 * {@code invokevirtual} instruction,
66
 * can invoke this method from Java source code.
67 68 69
 * <p>
 * Every call to a method handle specifies an intended method type,
 * which must exactly match the type of the method handle.
70
 * (The type is specified in the {@code invokevirtual} instruction,
71 72
 * via a {@code CONSTANT_NameAndType} constant pool entry.)
 * The call looks within the receiver object for a method
73
 * named {@code invokeExact} of the intended method type.
74
 * The call fails with a {@link WrongMethodTypeException}
75
 * if the method does not exist, even if there is an {@code invokeExact}
76
 * method of a closely similar signature.
77 78 79 80
 * As with other kinds
 * of methods in the JVM, signature matching during method linkage
 * is exact, and does not allow for language-level implicit conversions
 * such as {@code String} to {@code Object} or {@code short} to {@code int}.
81
 * <p>
82 83 84 85 86 87 88 89 90 91 92 93 94 95
 * Each individual method handle also contains a method named
 * {@link #invokeGeneric invokeGeneric}, whose type is the same
 * as {@code invokeExact}, and is therefore also reported by
 * the {@link #type type} accessor.
 * A call to {@code invokeGeneric} works the same as a call to
 * {@code invokeExact}, if the signature specified by the caller
 * exactly matches the method handle's own type.
 * If there is a type mismatch, {@code invokeGeneric} attempts
 * to adjust the type of the target method handle
 * (as if by a call to {@link #asType asType})
 * to obtain an exactly invokable target.
 * This allows a more powerful negotiation of method type
 * between caller and callee.
 * <p>
96 97 98 99 100 101 102
 * A method handle is an unrestricted capability to call a method.
 * A method handle can be formed on a non-public method by a class
 * that has access to that method; the resulting handle can be used
 * in any place by any caller who receives a reference to it.  Thus, access
 * checking is performed when the method handle is created, not
 * (as in reflection) every time it is called.  Handles to non-public
 * methods, or in non-public classes, should generally be kept secret.
103 104
 * They should not be passed to untrusted code unless their use from
 * the untrusted code would be harmless.
105
 * <p>
106 107
 * Bytecode in the JVM can directly call a method handle's
 * {@code invokeExact} method from an {@code invokevirtual} instruction.
108
 * The receiver class type must be {@code MethodHandle} and the method name
109
 * must be {@code invokeExact}.  The signature of the invocation
110 111
 * (after resolving symbolic type names) must exactly match the method type
 * of the target method.
112 113 114 115
 * Similarly, bytecode can directly call a method handle's {@code invokeGeneric}
 * method.  The signature of the invocation (after resolving symbolic type names)
 * must either exactly match the method type or be a valid argument to
 * the target's {@link #asType asType} method.
116
 * <p>
117 118
 * Every {@code invokeExact} and {@code invokeGeneric} method always
 * throws {@link java.lang.Throwable Throwable},
119 120 121 122 123 124
 * which is to say that there is no static restriction on what a method handle
 * can throw.  Since the JVM does not distinguish between checked
 * and unchecked exceptions (other than by their class, of course),
 * there is no particular effect on bytecode shape from ascribing
 * checked exceptions to method handle invocations.  But in Java source
 * code, methods which perform method handle calls must either explicitly
125 126 127
 * throw {@code java.lang.Throwable Throwable}, or else must catch all
 * throwables locally, rethrowing only those which are legal in the context,
 * and wrapping ones which are illegal.
128
 * <p>
129
 * Bytecode in the JVM can directly obtain a method handle
130 131 132
 * for any accessible method from a {@code ldc} instruction
 * which refers to a {@code CONSTANT_Methodref} or
 * {@code CONSTANT_InterfaceMethodref} constant pool entry.
133
 * <p>
134 135
 * Java code can also use a reflective API called
 * {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup}
136
 * for creating and calling method handles.
137 138 139 140
 * For example, a static method handle can be obtained
 * from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}.
 * There are also bridge methods from Core Reflection API objects,
 * such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.ureflect}.
141 142 143 144 145 146
 * <p>
 * A method reference may refer either to a static or non-static method.
 * In the non-static case, the method handle type includes an explicit
 * receiver argument, prepended before any other arguments.
 * In the method handle's type, the initial receiver argument is typed
 * according to the class under which the method was initially requested.
147
 * (E.g., if a non-static method handle is obtained via {@code ldc},
148 149 150 151 152 153 154 155
 * the type of the receiver is the class named in the constant pool entry.)
 * <p>
 * When a method handle to a virtual method is invoked, the method is
 * always looked up in the receiver (that is, the first argument).
 * <p>
 * A non-virtual method handles to a specific virtual method implementation
 * can also be created.  These do not perform virtual lookup based on
 * receiver type.  Such a method handle simulates the effect of
156
 * an {@code invokespecial} instruction to the same method.
157 158 159
 * <p>
 * Here are some examples of usage:
 * <p><blockquote><pre>
160 161 162 163 164 165 166 167 168 169
Object x, y; String s; int i;
MethodType mt; MethodHandle mh;
MethodHandles.Lookup lookup = MethodHandles.lookup();
// mt is {(char,char) =&gt; String}
mt = MethodType.methodType(String.class, char.class, char.class);
mh = lookup.findVirtual(String.class, "replace", mt);
// (Ljava/lang/String;CC)Ljava/lang/String;
s = mh.&lt;String&gt;invokeExact("daddy",'d','n');
assert(s.equals("nanny"));
// weakly typed invocation (using MHs.invoke)
170
s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
assert(s.equals("savvy"));
// mt is {Object[] =&gt; List}
mt = MethodType.methodType(java.util.List.class, Object[].class);
mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
// mt is {(Object,Object,Object) =&gt; Object}
mt = MethodType.genericMethodType(3);
mh = MethodHandles.collectArguments(mh, mt);
// mt is {(Object,Object,Object) =&gt; Object}
// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
x = mh.invokeExact((Object)1, (Object)2, (Object)3);
assert(x.equals(java.util.Arrays.asList(1,2,3)));
// mt is { =&gt; int}
mt = MethodType.methodType(int.class);
mh = lookup.findVirtual(java.util.List.class, "size", mt);
// (Ljava/util/List;)I
i = mh.&lt;int&gt;invokeExact(java.util.Arrays.asList(1,2,3));
assert(i == 3);
188 189 190 191 192 193 194 195 196 197 198 199 200
 * </pre></blockquote>
 * Each of the above calls generates a single invokevirtual instruction
 * with the name {@code invoke} and the type descriptors indicated in the comments.
 * The argument types are taken directly from the actual arguments,
 * while the return type is taken from the type parameter.
 * (This type parameter may be a primitive, and it defaults to {@code Object}.)
 * <p>
 * <em>A note on generic typing:</em>  Method handles do not represent
 * their function types in terms of Java parameterized (generic) types,
 * because there are three mismatches between function types and parameterized
 * Java types.
 * <ol>
 * <li>Method types range over all possible arities,
201
 * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
202 203 204 205 206 207 208 209
 * Generics are not variadic, and so cannot represent this.</li>
 * <li>Method types can specify arguments of primitive types,
 * which Java generic types cannot range over.</li>
 * <li>Higher order functions over method handles (combinators) are
 * often generic across a wide range of function types, including
 * those of multiple arities.  It is impossible to represent such
 * genericity with a Java type parameter.</li>
 * </ol>
210 211 212 213 214
 * Signature polymorphic methods in this class appear to be documented
 * as having type parameters for return types and a parameter, but that is
 * merely a documentation convention.  These type parameters do
 * not play a role in type-checking method handle invocations.
 * <p>
215 216 217 218
 * Like classes and strings, method handles that correspond to accessible
 * fields, methods, and constructors can be represented directly
 * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
 * Loading such a constant causes the component classes of its type to be loaded as necessary.
219 220 221 222 223 224 225 226 227 228
 *
 * @see MethodType
 * @see MethodHandles
 * @author John Rose, JSR 292 EG
 */
public abstract class MethodHandle
        // Note: This is an implementation inheritance hack, and will be removed
        // with a JVM change which moves the required hidden state onto this class.
        extends MethodHandleImpl
{
229
    private static Access IMPL_TOKEN = Access.getToken();
230

231
    // interface MethodHandle<R throws X extends Exception,A...>
232 233 234 235 236 237 238
    // { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }

    /**
     * Internal marker interface which distinguishes (to the Java compiler)
     * those methods which are signature polymorphic.
     */
    @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.TYPE})
239
    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
240
    @interface PolymorphicSignature { }
241 242

    private MethodType type;
243 244 245

    /**
     * Report the type of this method handle.
246
     * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
247 248
     * @return the method handle type
     */
249
    public final MethodType type() {
250 251 252 253
        return type;
    }

    /**
254 255 256 257
     * <em>CONSTRUCTOR WILL BE REMOVED FOR PFD:</em>
     * Temporary constructor in early versions of the Reference Implementation.
     * Method handle inheritance (if any) will be contained completely within
     * the {@code java.dyn} package.
258
     */
259 260 261 262 263
    // The constructor for MethodHandle may only be called by privileged code.
    // Subclasses may be in other packages, but must possess
    // a token which they obtained from MH with a security check.
    // @param token non-null object which proves access permission
    // @param type type (permanently assigned) of the new method handle
264 265
    protected MethodHandle(Access token, MethodType type) {
        super(token);
266 267 268 269 270 271 272
        Access.check(token);
        this.type = type;
    }

    private void initType(MethodType type) {
        type.getClass();  // elicit NPE
        if (this.type != null)  throw new InternalError();
273 274
        this.type = type;
    }
275 276 277 278 279 280 281 282 283 284

    static {
        // This hack allows the implementation package special access to
        // the internals of MethodHandle.  In particular, the MTImpl has all sorts
        // of cached information useful to the implementation code.
        MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
            public void initType(MethodHandle mh, MethodType type) { mh.initType(type); }
        });
    }

285 286
    /** Produce a printed representation that displays information about this call site
     *  that may be useful to the human reader.
287 288 289 290 291 292 293
     */
    @Override
    public String toString() {
        return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
    }

    /**
294 295
     * Invoke the method handle, allowing any caller signature, but requiring an exact signature match.
     * The signature at the call site of {@code invokeExact} must
296
     * exactly match this method handle's {@link #type type}.
297
     * No conversions are allowed on arguments or return values.
298 299
     * @throws WrongMethodTypeException if the target's type is not identical with the caller's type signature
     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
300
     */
301 302
    public final native @PolymorphicSignature <R,A> R invokeExact(A... args) throws Throwable;

303
    /**
304
     * Invoke the method handle, allowing any caller signature,
305
     * and optionally performing conversions for arguments and return types.
306
     * <p>
307 308
     * If the call site signature exactly matches this method handle's {@link #type type},
     * the call proceeds as if by {@link #invokeExact invokeExact}.
309 310
     * <p>
     * Otherwise, the call proceeds as if this method handle were first
311
     * adjusted by calling {@link #asType asType} to adjust this method handle
312
     * to the required type, and then the call proceeds as if by
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
     * {@link #invokeExact invokeExact} on the adjusted method handle.
     * <p>
     * There is no guarantee that the {@code asType} call is actually made.
     * If the JVM can predict the results of making the call, it may perform
     * adaptations directly on the caller's arguments,
     * and call the target method handle according to its own exact type.
     * <p>
     * If the method handle is equipped with a
     * {@linkplain #withTypeHandler type handler}, the handler must produce
     * an entry point of the call site's exact type.
     * Otherwise, the signature at the call site of {@code invokeGeneric} must
     * be a valid argument to the standard {@code asType} method.
     * In particular, the caller must specify the same argument arity
     * as the callee's type.
     * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type signature
     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
329
     */
330 331
    public final native @PolymorphicSignature <R,A> R invokeGeneric(A... args) throws Throwable;

332 333
    /**
     * Perform a varargs invocation, passing the arguments in the given array
334
     * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
335 336 337
     * which mentions only the type {@code Object}, and whose arity is the length
     * of the argument array.
     * <p>
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
     * Specifically, execution proceeds as if by the following steps,
     * although the methods are not guaranteed to be called if the JVM
     * can predict their effects.
     * <ul>
     * <li>Determine the length of the argument array as {@code N}.
     *     For a null reference, {@code N=0}. </li>
     * <li>Determine the generic type {@code TN} of {@code N} arguments as
     *     as {@code TN=MethodType.genericMethodType(N)}.</li>
     * <li>Force the original target method handle {@code MH0} to the
     *     required type, as {@code MH1 = MH0.asType(TN)}. </li>
     * <li>Spread the array into {@code N} separate arguments {@code A0, ...}. </li>
     * <li>Invoke the type-adjusted method handle on the unpacked arguments:
     *     MH1.invokeExact(A0, ...). </li>
     * <li>Take the return value as an {@code Object} reference. </li>
     * </ul>
353
     * <p>
354
     * Because of the action of the {@code asType} step, the following argument
355 356 357 358
     * conversions are applied as necessary:
     * <ul>
     * <li>reference casting
     * <li>unboxing
359
     * <li>widening primitive conversions
360
     * </ul>
361
     * <p>
362 363 364 365 366
     * The result returned by the call is boxed if it is a primitive,
     * or forced to null if the return type is void.
     * <p>
     * This call is equivalent to the following code:
     * <p><blockquote><pre>
367 368
     * MethodHandle invoker = MethodHandles.varargsInvoker(this.type(), 0);
     * Object result = invoker.invokeExact(this, arguments);
369 370 371
     * </pre></blockquote>
     * @param arguments the arguments to pass to the target
     * @return the result returned by the target
372 373 374
     * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the arguments
     * @throws Throwable anything thrown by the target method invocation
     * @see MethodHandles#varargsInvoker
375
     */
376
    public final Object invokeWithArguments(Object... arguments) throws Throwable {
377 378
        int argc = arguments == null ? 0 : arguments.length;
        MethodType type = type();
379 380 381 382
        if (type.parameterCount() != argc) {
            // simulate invokeGeneric
            return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
        }
383 384 385
        if (argc <= 10) {
            MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
            switch (argc) {
386 387
                case 0:  return invoker.invokeExact(this);
                case 1:  return invoker.invokeExact(this,
388
                                    arguments[0]);
389
                case 2:  return invoker.invokeExact(this,
390
                                    arguments[0], arguments[1]);
391
                case 3:  return invoker.invokeExact(this,
392
                                    arguments[0], arguments[1], arguments[2]);
393
                case 4:  return invoker.invokeExact(this,
394 395
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3]);
396
                case 5:  return invoker.invokeExact(this,
397 398
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3], arguments[4]);
399
                case 6:  return invoker.invokeExact(this,
400 401
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3], arguments[4], arguments[5]);
402
                case 7:  return invoker.invokeExact(this,
403 404 405
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3], arguments[4], arguments[5],
                                    arguments[6]);
406
                case 8:  return invoker.invokeExact(this,
407 408 409
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3], arguments[4], arguments[5],
                                    arguments[6], arguments[7]);
410
                case 9:  return invoker.invokeExact(this,
411 412 413
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3], arguments[4], arguments[5],
                                    arguments[6], arguments[7], arguments[8]);
414
                case 10:  return invoker.invokeExact(this,
415 416 417 418 419 420 421 422 423
                                    arguments[0], arguments[1], arguments[2],
                                    arguments[3], arguments[4], arguments[5],
                                    arguments[6], arguments[7], arguments[8],
                                    arguments[9]);
            }
        }

        // more than ten arguments get boxed in a varargs list:
        MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
424
        return invoker.invokeExact(this, arguments);
425
    }
426 427 428
    /** Equivalent to {@code invokeWithArguments(arguments.toArray())}. */
    public final Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
        return invokeWithArguments(arguments.toArray());
429
    }
430 431 432 433 434 435 436
    @Deprecated
    public final Object invokeVarargs(Object... arguments) throws Throwable {
        return invokeWithArguments(arguments);
    }
    @Deprecated
    public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
        return invokeWithArguments(arguments.toArray());
437 438
    }

439
    /**
440
     * Produce an adapter method handle which adapts the type of the
441 442
     * current method handle to a new type
     * The resulting method handle is guaranteed to report a type
443 444 445 446
     * which is equal to the desired new type.
     * <p>
     * If the original type and new type are equal, returns {@code this}.
     * <p>
447 448 449 450 451 452
     * This method provides the crucial behavioral difference between
     * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.  The two methods
     * perform the same steps when the caller's type descriptor is identical
     * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric}
     * also calls {@code asType} (or some internal equivalent) in order
     * to match up the caller's and callee's types.
453
     * <p>
454 455 456
     * This method is equivalent to {@link MethodHandles#convertArguments convertArguments},
     * except for method handles produced by {@link #withTypeHandler withTypeHandler},
     * in which case the specified type handler is used for calls to {@code asType}.
457
     * <p>
458 459 460 461 462
     * Note that the default behavior of {@code asType} only performs
     * pairwise argument conversion and return value conversion.
     * Because of this, unless the method handle has a type handler,
     * the original type and new type must have the same number of arguments.
     *
463 464 465 466
     * @param newType the expected type of the new method handle
     * @return a method handle which delegates to {@code this} after performing
     *           any necessary argument conversions, and arranges for any
     *           necessary return value conversions
467
     * @throws WrongMethodTypeException if the conversion cannot be made
468 469
     * @see MethodHandles#convertArguments
     */
470
    public MethodHandle asType(MethodType newType) {
471 472 473 474 475 476
        return MethodHandles.convertArguments(this, newType);
    }

    /**
     * Produce a method handle which adapts, as its <i>target</i>,
     * the current method handle.  The type of the adapter will be
477 478 479 480 481 482 483 484
     * the same as the type of the target, except that the final
     * {@code arrayLength} parameters of the target's type are replaced
     * by a single array parameter of type {@code arrayType}.
     * <p>
     * If the array element type differs from any of the corresponding
     * argument types on original target,
     * the original target is adapted to take the array elements directly,
     * as if by a call to {@link #asType asType}.
485 486 487 488 489 490 491 492 493 494 495 496 497
     * <p>
     * When called, the adapter replaces a trailing array argument
     * by the array's elements, each as its own argument to the target.
     * (The order of the arguments is preserved.)
     * They are converted pairwise by casting and/or unboxing
     * to the types of the trailing parameters of the target.
     * Finally the target is called.
     * What the target eventually returns is returned unchanged by the adapter.
     * <p>
     * Before calling the target, the adapter verifies that the array
     * contains exactly enough elements to provide a correct argument count
     * to the target method handle.
     * (The array may also be null when zero elements are required.)
498 499 500
     * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
     * @param arrayLength the number of arguments to spread from an incoming array argument
     * @return a new method handle which spreads its final array argument,
501
     *         before calling the original method handle
502
     * @throws IllegalArgumentException if {@code arrayType} is not an array type
503
     * @throws IllegalArgumentException if target does not have at least
504 505
     *         {@code arrayLength} parameter types
     * @throws WrongMethodTypeException if the implied {@code asType} call fails
506
     */
507 508 509
    public final MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
        Class<?> arrayElement = arrayType.getComponentType();
        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
510 511
        MethodType oldType = type();
        int nargs = oldType.parameterCount();
512 513
        if (nargs < arrayLength)  throw newIllegalArgumentException("bad spread array length");
        int keepPosArgs = nargs - arrayLength;
514
        MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
515
        newType = newType.insertParameterTypes(keepPosArgs, arrayElement);
516 517 518 519 520 521 522
        return MethodHandles.spreadArguments(this, newType);
    }

    /**
     * Produce a method handle which adapts, as its <i>target</i>,
     * the current method handle.  The type of the adapter will be
     * the same as the type of the target, except that a single trailing
523 524 525 526 527 528
     * parameter (usually of type {@code arrayType}) is replaced by
     * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
     * <p>
     * If the array type differs from the final argument type on original target,
     * the original target is adapted to take the array type directly,
     * as if by a call to {@link #asType asType}.
529
     * <p>
530 531
     * When called, the adapter replaces its trailing {@code arrayLength}
     * arguments by a single new array of type {@code arrayType}, whose elements
532 533 534 535
     * comprise (in order) the replaced arguments.
     * Finally the target is called.
     * What the target eventually returns is returned unchanged by the adapter.
     * <p>
536 537 538
     * (The array may also be a shared constant when {@code arrayLength} is zero.)
     * @param arrayType usually {@code Object[]}, the type of the array argument which will collect the arguments
     * @param arrayLength the number of arguments to collect into a new array argument
539 540
     * @return a new method handle which collects some trailing argument
     *         into an array, before calling the original method handle
541 542 543
     * @throws IllegalArgumentException if {@code arrayType} is not an array type
               or {@code arrayType} is not assignable to this method handle's trailing parameter type
     * @throws IllegalArgumentException if {@code arrayLength} is not
544
     *         a legal array size
545
     * @throws WrongMethodTypeException if the implied {@code asType} call fails
546
     */
547 548 549
    public final MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
        Class<?> arrayElement = arrayType.getComponentType();
        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
550 551 552
        MethodType oldType = type();
        int nargs = oldType.parameterCount();
        MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
553 554
        newType = newType.insertParameterTypes(nargs-1,
                    java.util.Collections.<Class<?>>nCopies(arrayLength, arrayElement));
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
        return MethodHandles.collectArguments(this, newType);
    }

    /**
     * Produce a method handle which binds the given argument
     * to the current method handle as <i>target</i>.
     * The type of the bound handle will be
     * the same as the type of the target, except that a single leading
     * reference parameter will be omitted.
     * <p>
     * When called, the bound handle inserts the given value {@code x}
     * as a new leading argument to the target.  The other arguments are
     * also passed unchanged.
     * What the target eventually returns is returned unchanged by the bound handle.
     * <p>
     * The reference {@code x} must be convertible to the first parameter
     * type of the target.
     * @param x  the value to bind to the first argument of the target
     * @return a new method handle which collects some trailing argument
     *         into an array, before calling the original method handle
     * @throws IllegalArgumentException if the target does not have a
     *         leading parameter type that is a reference type
     * @throws ClassCastException if {@code x} cannot be converted
     *         to the leading parameter type of the target
579
     * @see MethodHandles#insertArguments
580 581 582 583
     */
    public final MethodHandle bindTo(Object x) {
        return MethodHandles.insertArguments(this, 0, x);
    }
584

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
    /**
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
     * Create a new method handle with the same type as this one,
     * but whose {@code asType} method invokes the given
     * {@code typeHandler} on this method handle,
     * instead of the standard {@code MethodHandles.convertArguments}.
     * <p>
     * The new method handle will have the same behavior as the
     * old one when invoked by {@code invokeExact}.
     * For {@code invokeGeneric} calls which exactly match
     * the method type, the two method handles will also
     * have the same behavior.
     * For other {@code invokeGeneric} calls, the {@code typeHandler}
     * will control the behavior of the new method handle.
     * <p>
     * Thus, a method handle with an {@code asType} handler can
     * be configured to accept more than one arity of {@code invokeGeneric}
     * call, and potentially every possible arity.
     * It can also be configured to supply default values for
     * optional arguments, when the caller does not specify them.
     * <p>
     * The given method handle must take two arguments and return
     * one result.  The result it returns must be a method handle
     * of exactly the requested type.  If the result returned by
     * the target is null, a {@link NullPointerException} is thrown,
     * else if the type of the target does not exactly match
     * the requested type, a {@link WrongMethodTypeException} is thrown.
     * <p>
     * Therefore, the type handler is invoked as if by this code:
     * <blockquote><pre>
     * MethodHandle target = this;      // original method handle
     * MethodHandle adapter = ...;      // adapted method handle
     * MethodType requestedType = ...;  // argument to asType()
     * if (type().equals(requestedType))
     *    return adapter;
     * MethodHandle result = (MethodHandle)
     *    typeHandler.invokeGeneric(target, requestedType);
     * if (!result.type().equals(requestedType))
     *    throw new WrongMethodTypeException();
     * return result;
     * </pre></blockquote>
     * <p>
     * For example, here is a list-making variable-arity method handle:
     * <blockquote><pre>
MethodHandle makeEmptyList = MethodHandles.constant(List.class, Arrays.asList());
MethodHandle asList = lookup()
  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
static MethodHandle collectingTypeHandler(MethodHandle base, MethodType newType) {
  return asList.asCollector(Object[].class, newType.parameterCount()).asType(newType);
}
MethodHandle collectingTypeHandler = lookup()
  .findStatic(lookup().lookupClass(), "collectingTypeHandler",
     methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
MethodHandle makeAnyList = makeEmptyList.withTypeHandler(collectingTypeHandler);
639

640 641 642 643 644 645 646 647
System.out.println(makeAnyList.invokeGeneric()); // prints []
System.out.println(makeAnyList.invokeGeneric(1)); // prints [1]
System.out.println(makeAnyList.invokeGeneric("two", "too")); // prints [two, too]
     * <pre><blockquote>
     */
    public MethodHandle withTypeHandler(MethodHandle typeHandler) {
        return MethodHandles.withTypeHandler(this, typeHandler);
    }
648
}