< prev index next >

src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java

Print this page

  1 /*
  2  * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * 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  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any

234 public final class LambdaMetafactory {
235 
236     private LambdaMetafactory() {}
237 
238     /** Flag for {@link #altMetafactory} indicating the lambda object
239      * must be serializable */
240     public static final int FLAG_SERIALIZABLE = 1 << 0;
241 
242     /**
243      * Flag for {@link #altMetafactory} indicating the lambda object implements
244      * other interfaces besides {@code Serializable}
245      */
246     public static final int FLAG_MARKERS = 1 << 1;
247 
248     /**
249      * Flag for alternate metafactories indicating the lambda object requires
250      * additional methods that invoke the {@code implementation}
251      */
252     public static final int FLAG_BRIDGES = 1 << 2;
253 




254     private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
255     private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
256 
257     // LambdaMetafactory bootstrap methods are startup sensitive, and may be
258     // special cased in java.lang.invoke.BootstrapMethodInvoker to ensure
259     // methods are invoked with exact type information to avoid generating
260     // code for runtime checks. Take care any changes or additions here are
261     // reflected there as appropriate.
262 
263     /**
264      * Facilitates the creation of simple "function objects" that implement one
265      * or more interfaces by delegation to a provided {@link MethodHandle},
266      * after appropriate type adaptation and partial evaluation of arguments.
267      * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
268      * call sites, to support the <em>lambda expression</em> and <em>method
269      * reference expression</em> features of the Java Programming Language.
270      *
271      * <p>This is the standard, streamlined metafactory; additional flexibility
272      * is provided by {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}.
273      * A general description of the behavior of this method is provided

319      * @throws SecurityException If a security manager is present, and it
320      *         <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
321      *         from {@code caller} to the package of {@code implementation}.
322      */
323     public static CallSite metafactory(MethodHandles.Lookup caller,
324                                        String interfaceMethodName,
325                                        MethodType factoryType,
326                                        MethodType interfaceMethodType,
327                                        MethodHandle implementation,
328                                        MethodType dynamicMethodType)
329             throws LambdaConversionException {
330         AbstractValidatingLambdaMetafactory mf;
331         mf = new InnerClassLambdaMetafactory(Objects.requireNonNull(caller),
332                                              Objects.requireNonNull(factoryType),
333                                              Objects.requireNonNull(interfaceMethodName),
334                                              Objects.requireNonNull(interfaceMethodType),
335                                              Objects.requireNonNull(implementation),
336                                              Objects.requireNonNull(dynamicMethodType),
337                                              false,
338                                              EMPTY_CLASS_ARRAY,
339                                              EMPTY_MT_ARRAY);

340         mf.validateMetafactoryArgs();
341         return mf.buildCallSite();
342     }
343 
344     /**
345      * Facilitates the creation of simple "function objects" that implement one
346      * or more interfaces by delegation to a provided {@link MethodHandle},
347      * after appropriate type adaptation and partial evaluation of arguments.
348      * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
349      * call sites, to support the <em>lambda expression</em> and <em>method
350      * reference expression</em> features of the Java Programming Language.
351      *
352      * <p>This is the general, more flexible metafactory; a streamlined version
353      * is provided by {@link #metafactory(java.lang.invoke.MethodHandles.Lookup,
354      * String, MethodType, MethodType, MethodHandle, MethodType)}.
355      * A general description of the behavior of this method is provided
356      * {@link LambdaMetafactory above}.
357      *
358      * <p>The argument list for this method includes three fixed parameters,
359      * corresponding to the parameters automatically stacked by the VM for the

365      *  CallSite altMetafactory(MethodHandles.Lookup caller,
366      *                          String interfaceMethodName,
367      *                          MethodType factoryType,
368      *                          Object... args)
369      * }</pre>
370      *
371      * <p>but it behaves as if the argument list is as follows:
372      *
373      * <pre>{@code
374      *  CallSite altMetafactory(MethodHandles.Lookup caller,
375      *                          String interfaceMethodName,
376      *                          MethodType factoryType,
377      *                          MethodType interfaceMethodType,
378      *                          MethodHandle implementation,
379      *                          MethodType dynamicMethodType,
380      *                          int flags,
381      *                          int altInterfaceCount,        // IF flags has MARKERS set
382      *                          Class... altInterfaces,       // IF flags has MARKERS set
383      *                          int altMethodCount,           // IF flags has BRIDGES set
384      *                          MethodType... altMethods      // IF flags has BRIDGES set

385      *                          )
386      * }</pre>
387      *
388      * <p>Arguments that appear in the argument list for
389      * {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
390      * have the same specification as in that method.  The additional arguments
391      * are interpreted as follows:
392      * <ul>
393      *     <li>{@code flags} indicates additional options; this is a bitwise
394      *     OR of desired flags.  Defined flags are {@link #FLAG_BRIDGES},
395      *     {@link #FLAG_MARKERS}, and {@link #FLAG_SERIALIZABLE}.</li>
396      *     <li>{@code altInterfaceCount} is the number of additional interfaces
397      *     the function object should implement, and is present if and only if the
398      *     {@code FLAG_MARKERS} flag is set.</li>
399      *     <li>{@code altInterfaces} is a variable-length list of additional
400      *     interfaces to implement, whose length equals {@code altInterfaceCount},
401      *     and is present if and only if the {@code FLAG_MARKERS} flag is set.</li>
402      *     <li>{@code altMethodCount} is the number of additional method signatures
403      *     the function object should implement, and is present if and only if
404      *     the {@code FLAG_BRIDGES} flag is set.</li>
405      *     <li>{@code altMethods} is a variable-length list of additional
406      *     methods signatures to implement, whose length equals {@code altMethodCount},
407      *     and is present if and only if the {@code FLAG_BRIDGES} flag is set.</li>




408      * </ul>
409      *
410      * <p>Each class named by {@code altInterfaces} is subject to the same
411      * restrictions as {@code Rd}, the return type of {@code factoryType},
412      * as described {@link LambdaMetafactory above}.  Each {@code MethodType}
413      * named by {@code altMethods} is subject to the same restrictions as
414      * {@code interfaceMethodType}, as described {@link LambdaMetafactory above}.
415      *
416      * <p>When FLAG_SERIALIZABLE is set in {@code flags}, the function objects
417      * will implement {@code Serializable}, and will have a {@code writeReplace}
418      * method that returns an appropriate {@link SerializedLambda}.  The
419      * {@code caller} class must have an appropriate {@code $deserializeLambda$}
420      * method, as described in {@link SerializedLambda}.
421      *



422      * <p>When the target of the {@code CallSite} returned from this method is
423      * invoked, the resulting function objects are instances of a class with
424      * the following properties:
425      * <ul>
426      *     <li>The class implements the interface named by the return type
427      *     of {@code factoryType} and any interfaces named by {@code altInterfaces}</li>
428      *     <li>The class declares methods with the name given by {@code interfaceMethodName},
429      *     and the signature given by {@code interfaceMethodType} and additional signatures
430      *     given by {@code altMethods}</li>
431      *     <li>The class may override methods from {@code Object}, and may
432      *     implement methods related to serialization.</li>
433      * </ul>
434      *
435      * @param caller Represents a lookup context with the accessibility
436      *               privileges of the caller.  Specifically, the lookup context
437      *               must have {@linkplain MethodHandles.Lookup#hasFullPrivilegeAccess()
438      *               full privilege access}.
439      *               When used with {@code invokedynamic}, this is stacked
440      *               automatically by the VM.
441      * @param interfaceMethodName The name of the method to implement.  When used with

470      * @throws SecurityException If a security manager is present, and it
471      *         <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
472      *         from {@code caller} to the package of {@code implementation}.
473      */
474     public static CallSite altMetafactory(MethodHandles.Lookup caller,
475                                           String interfaceMethodName,
476                                           MethodType factoryType,
477                                           Object... args)
478             throws LambdaConversionException {
479         Objects.requireNonNull(caller);
480         Objects.requireNonNull(interfaceMethodName);
481         Objects.requireNonNull(factoryType);
482         Objects.requireNonNull(args);
483         int argIndex = 0;
484         MethodType interfaceMethodType = extractArg(args, argIndex++, MethodType.class);
485         MethodHandle implementation = extractArg(args, argIndex++, MethodHandle.class);
486         MethodType dynamicMethodType = extractArg(args, argIndex++, MethodType.class);
487         int flags = extractArg(args, argIndex++, Integer.class);
488         Class<?>[] altInterfaces = EMPTY_CLASS_ARRAY;
489         MethodType[] altMethods = EMPTY_MT_ARRAY;

490         if ((flags & FLAG_MARKERS) != 0) {
491             int altInterfaceCount = extractArg(args, argIndex++, Integer.class);
492             if (altInterfaceCount < 0) {
493                 throw new IllegalArgumentException("negative argument count");
494             }
495             if (altInterfaceCount > 0) {
496                 altInterfaces = extractArgs(args, argIndex, Class.class, altInterfaceCount);
497                 argIndex += altInterfaceCount;
498             }
499         }
500         if ((flags & FLAG_BRIDGES) != 0) {
501             int altMethodCount = extractArg(args, argIndex++, Integer.class);
502             if (altMethodCount < 0) {
503                 throw new IllegalArgumentException("negative argument count");
504             }
505             if (altMethodCount > 0) {
506                 altMethods = extractArgs(args, argIndex, MethodType.class, altMethodCount);
507                 argIndex += altMethodCount;
508             }
509         }





510         if (argIndex < args.length) {
511             throw new IllegalArgumentException("too many arguments");
512         }
513 
514         boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);
515         if (isSerializable) {
516             boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(factoryType.returnType());
517             for (Class<?> c : altInterfaces)
518                 foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
519             if (!foundSerializableSupertype) {
520                 altInterfaces = Arrays.copyOf(altInterfaces, altInterfaces.length + 1);
521                 altInterfaces[altInterfaces.length-1] = Serializable.class;
522             }
523         }
524 
525         AbstractValidatingLambdaMetafactory mf
526                 = new InnerClassLambdaMetafactory(caller,
527                                                   factoryType,
528                                                   interfaceMethodName,
529                                                   interfaceMethodType,
530                                                   implementation,
531                                                   dynamicMethodType,
532                                                   isSerializable,
533                                                   altInterfaces,
534                                                   altMethods);

535         mf.validateMetafactoryArgs();
536         return mf.buildCallSite();
537     }
538 
539     private static <T> T extractArg(Object[] args, int index, Class<T> type) {
540         if (index >= args.length) {
541             throw new IllegalArgumentException("missing argument");
542         }
543         Object result = Objects.requireNonNull(args[index]);
544         if (!type.isInstance(result)) {
545             throw new IllegalArgumentException("argument has wrong type");
546         }
547         return type.cast(result);
548     }
549 
550     private static <T> T[] extractArgs(Object[] args, int index, Class<T> type, int count) {
551         @SuppressWarnings("unchecked")
552         T[] result = (T[]) Array.newInstance(type, count);
553         for (int i = 0; i < count; i++) {
554             result[i] = extractArg(args, index + i, type);

  1 /*
  2  * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * 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  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any

234 public final class LambdaMetafactory {
235 
236     private LambdaMetafactory() {}
237 
238     /** Flag for {@link #altMetafactory} indicating the lambda object
239      * must be serializable */
240     public static final int FLAG_SERIALIZABLE = 1 << 0;
241 
242     /**
243      * Flag for {@link #altMetafactory} indicating the lambda object implements
244      * other interfaces besides {@code Serializable}
245      */
246     public static final int FLAG_MARKERS = 1 << 1;
247 
248     /**
249      * Flag for alternate metafactories indicating the lambda object requires
250      * additional methods that invoke the {@code implementation}
251      */
252     public static final int FLAG_BRIDGES = 1 << 2;
253 
254     /** Flag for {@link #altMetafactory} indicating the lambda object
255      * must be a {@code Quotable} object, inspectable using code reflection. */
256     public static final int FLAG_QUOTABLE = 1 << 3;
257 
258     private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
259     private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
260 
261     // LambdaMetafactory bootstrap methods are startup sensitive, and may be
262     // special cased in java.lang.invoke.BootstrapMethodInvoker to ensure
263     // methods are invoked with exact type information to avoid generating
264     // code for runtime checks. Take care any changes or additions here are
265     // reflected there as appropriate.
266 
267     /**
268      * Facilitates the creation of simple "function objects" that implement one
269      * or more interfaces by delegation to a provided {@link MethodHandle},
270      * after appropriate type adaptation and partial evaluation of arguments.
271      * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
272      * call sites, to support the <em>lambda expression</em> and <em>method
273      * reference expression</em> features of the Java Programming Language.
274      *
275      * <p>This is the standard, streamlined metafactory; additional flexibility
276      * is provided by {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}.
277      * A general description of the behavior of this method is provided

323      * @throws SecurityException If a security manager is present, and it
324      *         <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
325      *         from {@code caller} to the package of {@code implementation}.
326      */
327     public static CallSite metafactory(MethodHandles.Lookup caller,
328                                        String interfaceMethodName,
329                                        MethodType factoryType,
330                                        MethodType interfaceMethodType,
331                                        MethodHandle implementation,
332                                        MethodType dynamicMethodType)
333             throws LambdaConversionException {
334         AbstractValidatingLambdaMetafactory mf;
335         mf = new InnerClassLambdaMetafactory(Objects.requireNonNull(caller),
336                                              Objects.requireNonNull(factoryType),
337                                              Objects.requireNonNull(interfaceMethodName),
338                                              Objects.requireNonNull(interfaceMethodType),
339                                              Objects.requireNonNull(implementation),
340                                              Objects.requireNonNull(dynamicMethodType),
341                                              false,
342                                              EMPTY_CLASS_ARRAY,
343                                              EMPTY_MT_ARRAY,
344                                  null);
345         mf.validateMetafactoryArgs();
346         return mf.buildCallSite();
347     }
348 
349     /**
350      * Facilitates the creation of simple "function objects" that implement one
351      * or more interfaces by delegation to a provided {@link MethodHandle},
352      * after appropriate type adaptation and partial evaluation of arguments.
353      * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
354      * call sites, to support the <em>lambda expression</em> and <em>method
355      * reference expression</em> features of the Java Programming Language.
356      *
357      * <p>This is the general, more flexible metafactory; a streamlined version
358      * is provided by {@link #metafactory(java.lang.invoke.MethodHandles.Lookup,
359      * String, MethodType, MethodType, MethodHandle, MethodType)}.
360      * A general description of the behavior of this method is provided
361      * {@link LambdaMetafactory above}.
362      *
363      * <p>The argument list for this method includes three fixed parameters,
364      * corresponding to the parameters automatically stacked by the VM for the

370      *  CallSite altMetafactory(MethodHandles.Lookup caller,
371      *                          String interfaceMethodName,
372      *                          MethodType factoryType,
373      *                          Object... args)
374      * }</pre>
375      *
376      * <p>but it behaves as if the argument list is as follows:
377      *
378      * <pre>{@code
379      *  CallSite altMetafactory(MethodHandles.Lookup caller,
380      *                          String interfaceMethodName,
381      *                          MethodType factoryType,
382      *                          MethodType interfaceMethodType,
383      *                          MethodHandle implementation,
384      *                          MethodType dynamicMethodType,
385      *                          int flags,
386      *                          int altInterfaceCount,        // IF flags has MARKERS set
387      *                          Class... altInterfaces,       // IF flags has MARKERS set
388      *                          int altMethodCount,           // IF flags has BRIDGES set
389      *                          MethodType... altMethods      // IF flags has BRIDGES set
390      *                          MethodHandle quotableField    // IF flags has QUOTABLE set
391      *                          )
392      * }</pre>
393      *
394      * <p>Arguments that appear in the argument list for
395      * {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
396      * have the same specification as in that method.  The additional arguments
397      * are interpreted as follows:
398      * <ul>
399      *     <li>{@code flags} indicates additional options; this is a bitwise
400      *     OR of desired flags.  Defined flags are {@link #FLAG_BRIDGES},
401      *     {@link #FLAG_MARKERS}, and {@link #FLAG_SERIALIZABLE}.</li>
402      *     <li>{@code altInterfaceCount} is the number of additional interfaces
403      *     the function object should implement, and is present if and only if the
404      *     {@code FLAG_MARKERS} flag is set.</li>
405      *     <li>{@code altInterfaces} is a variable-length list of additional
406      *     interfaces to implement, whose length equals {@code altInterfaceCount},
407      *     and is present if and only if the {@code FLAG_MARKERS} flag is set.</li>
408      *     <li>{@code altMethodCount} is the number of additional method signatures
409      *     the function object should implement, and is present if and only if
410      *     the {@code FLAG_BRIDGES} flag is set.</li>
411      *     <li>{@code altMethods} is a variable-length list of additional
412      *     methods signatures to implement, whose length equals {@code altMethodCount},
413      *     and is present if and only if the {@code FLAG_BRIDGES} flag is set.</li>
414      *     <li>{@code quotableField} is a
415      *     {@linkplain MethodHandles.Lookup#findGetter(Class, String, Class) getter} method handle
416      *     that is used to retrieve the string representation of the quotable lambda's associated
417      *     intermediate representation.</li>
418      * </ul>
419      *
420      * <p>Each class named by {@code altInterfaces} is subject to the same
421      * restrictions as {@code Rd}, the return type of {@code factoryType},
422      * as described {@link LambdaMetafactory above}.  Each {@code MethodType}
423      * named by {@code altMethods} is subject to the same restrictions as
424      * {@code interfaceMethodType}, as described {@link LambdaMetafactory above}.
425      *
426      * <p>When FLAG_SERIALIZABLE is set in {@code flags}, the function objects
427      * will implement {@code Serializable}, and will have a {@code writeReplace}
428      * method that returns an appropriate {@link SerializedLambda}.  The
429      * {@code caller} class must have an appropriate {@code $deserializeLambda$}
430      * method, as described in {@link SerializedLambda}.
431      *
432      * <p>When FLAG_QUOTABLE is set in {@code flags}, the function objects
433      * will implement {@code Quotable}.
434      *
435      * <p>When the target of the {@code CallSite} returned from this method is
436      * invoked, the resulting function objects are instances of a class with
437      * the following properties:
438      * <ul>
439      *     <li>The class implements the interface named by the return type
440      *     of {@code factoryType} and any interfaces named by {@code altInterfaces}</li>
441      *     <li>The class declares methods with the name given by {@code interfaceMethodName},
442      *     and the signature given by {@code interfaceMethodType} and additional signatures
443      *     given by {@code altMethods}</li>
444      *     <li>The class may override methods from {@code Object}, and may
445      *     implement methods related to serialization.</li>
446      * </ul>
447      *
448      * @param caller Represents a lookup context with the accessibility
449      *               privileges of the caller.  Specifically, the lookup context
450      *               must have {@linkplain MethodHandles.Lookup#hasFullPrivilegeAccess()
451      *               full privilege access}.
452      *               When used with {@code invokedynamic}, this is stacked
453      *               automatically by the VM.
454      * @param interfaceMethodName The name of the method to implement.  When used with

483      * @throws SecurityException If a security manager is present, and it
484      *         <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
485      *         from {@code caller} to the package of {@code implementation}.
486      */
487     public static CallSite altMetafactory(MethodHandles.Lookup caller,
488                                           String interfaceMethodName,
489                                           MethodType factoryType,
490                                           Object... args)
491             throws LambdaConversionException {
492         Objects.requireNonNull(caller);
493         Objects.requireNonNull(interfaceMethodName);
494         Objects.requireNonNull(factoryType);
495         Objects.requireNonNull(args);
496         int argIndex = 0;
497         MethodType interfaceMethodType = extractArg(args, argIndex++, MethodType.class);
498         MethodHandle implementation = extractArg(args, argIndex++, MethodHandle.class);
499         MethodType dynamicMethodType = extractArg(args, argIndex++, MethodType.class);
500         int flags = extractArg(args, argIndex++, Integer.class);
501         Class<?>[] altInterfaces = EMPTY_CLASS_ARRAY;
502         MethodType[] altMethods = EMPTY_MT_ARRAY;
503         MethodHandle quotableField = null;
504         if ((flags & FLAG_MARKERS) != 0) {
505             int altInterfaceCount = extractArg(args, argIndex++, Integer.class);
506             if (altInterfaceCount < 0) {
507                 throw new IllegalArgumentException("negative argument count");
508             }
509             if (altInterfaceCount > 0) {
510                 altInterfaces = extractArgs(args, argIndex, Class.class, altInterfaceCount);
511                 argIndex += altInterfaceCount;
512             }
513         }
514         if ((flags & FLAG_BRIDGES) != 0) {
515             int altMethodCount = extractArg(args, argIndex++, Integer.class);
516             if (altMethodCount < 0) {
517                 throw new IllegalArgumentException("negative argument count");
518             }
519             if (altMethodCount > 0) {
520                 altMethods = extractArgs(args, argIndex, MethodType.class, altMethodCount);
521                 argIndex += altMethodCount;
522             }
523         }
524         if ((flags & FLAG_QUOTABLE) != 0) {
525             quotableField = extractArg(args, argIndex++, MethodHandle.class);
526             altInterfaces = Arrays.copyOf(altInterfaces, altInterfaces.length + 1);
527             altInterfaces[altInterfaces.length-1] = InnerClassLambdaMetafactory.CodeReflectionSupport.QUOTABLE_CLASS;
528         }
529         if (argIndex < args.length) {
530             throw new IllegalArgumentException("too many arguments");
531         }
532 
533         boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);
534         if (isSerializable) {
535             boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(factoryType.returnType());
536             for (Class<?> c : altInterfaces)
537                 foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
538             if (!foundSerializableSupertype) {
539                 altInterfaces = Arrays.copyOf(altInterfaces, altInterfaces.length + 1);
540                 altInterfaces[altInterfaces.length-1] = Serializable.class;
541             }
542         }
543 
544         AbstractValidatingLambdaMetafactory mf
545                 = new InnerClassLambdaMetafactory(caller,
546                                                   factoryType,
547                                                   interfaceMethodName,
548                                                   interfaceMethodType,
549                                                   implementation,
550                                                   dynamicMethodType,
551                                                   isSerializable,
552                                                   altInterfaces,
553                                                   altMethods,
554                                                   quotableField);
555         mf.validateMetafactoryArgs();
556         return mf.buildCallSite();
557     }
558 
559     private static <T> T extractArg(Object[] args, int index, Class<T> type) {
560         if (index >= args.length) {
561             throw new IllegalArgumentException("missing argument");
562         }
563         Object result = Objects.requireNonNull(args[index]);
564         if (!type.isInstance(result)) {
565             throw new IllegalArgumentException("argument has wrong type");
566         }
567         return type.cast(result);
568     }
569 
570     private static <T> T[] extractArgs(Object[] args, int index, Class<T> type, int count) {
571         @SuppressWarnings("unchecked")
572         T[] result = (T[]) Array.newInstance(type, count);
573         for (int i = 0; i < count; i++) {
574             result[i] = extractArg(args, index + i, type);
< prev index next >