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);
|