< prev index next >

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

Print this page




 313      *                                   are violated, or the lookup context
 314      *                                   does not have private access privileges.
 315      */
 316     public static CallSite metafactory(MethodHandles.Lookup caller,
 317                                        String invokedName,
 318                                        MethodType invokedType,
 319                                        MethodType samMethodType,
 320                                        MethodHandle implMethod,
 321                                        MethodType instantiatedMethodType)
 322             throws LambdaConversionException {
 323         AbstractValidatingLambdaMetafactory mf;
 324         mf = new InnerClassLambdaMetafactory(caller, invokedType,
 325                                              invokedName, samMethodType,
 326                                              implMethod, instantiatedMethodType,
 327                                              false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
 328         mf.validateMetafactoryArgs();
 329         return mf.buildCallSite();
 330     }
 331 
 332     /**

































































 333      * Facilitates the creation of simple "function objects" that implement one
 334      * or more interfaces by delegation to a provided {@link MethodHandle},
 335      * after appropriate type adaptation and partial evaluation of arguments.
 336      * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
 337      * call sites, to support the <em>lambda expression</em> and <em>method
 338      * reference expression</em> features of the Java Programming Language.
 339      *
 340      * <p>This is the general, more flexible metafactory; a streamlined version
 341      * is provided by {@link #metafactory(java.lang.invoke.MethodHandles.Lookup,
 342      * String, MethodType, MethodType, MethodHandle, MethodType)}.
 343      * A general description of the behavior of this method is provided
 344      * {@link LambdaMetafactory above}.
 345      *
 346      * <p>The argument list for this method includes three fixed parameters,
 347      * corresponding to the parameters automatically stacked by the VM for the
 348      * bootstrap method in an {@code invokedynamic} invocation, and an {@code Object[]}
 349      * parameter that contains additional parameters.  The declared argument
 350      * list for this method is:
 351      *
 352      * <pre>{@code


 485         boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);
 486         if (isSerializable) {
 487             boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType());
 488             for (Class<?> c : markerInterfaces)
 489                 foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
 490             if (!foundSerializableSupertype) {
 491                 markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
 492                 markerInterfaces[markerInterfaces.length-1] = Serializable.class;
 493             }
 494         }
 495 
 496         AbstractValidatingLambdaMetafactory mf
 497                 = new InnerClassLambdaMetafactory(caller, invokedType,
 498                                                   invokedName, samMethodType,
 499                                                   implMethod,
 500                                                   instantiatedMethodType,
 501                                                   isSerializable,
 502                                                   markerInterfaces, bridges);
 503         mf.validateMetafactoryArgs();
 504         return mf.buildCallSite();

























































 505     }
 506 }


 313      *                                   are violated, or the lookup context
 314      *                                   does not have private access privileges.
 315      */
 316     public static CallSite metafactory(MethodHandles.Lookup caller,
 317                                        String invokedName,
 318                                        MethodType invokedType,
 319                                        MethodType samMethodType,
 320                                        MethodHandle implMethod,
 321                                        MethodType instantiatedMethodType)
 322             throws LambdaConversionException {
 323         AbstractValidatingLambdaMetafactory mf;
 324         mf = new InnerClassLambdaMetafactory(caller, invokedType,
 325                                              invokedName, samMethodType,
 326                                              implMethod, instantiatedMethodType,
 327                                              false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
 328         mf.validateMetafactoryArgs();
 329         return mf.buildCallSite();
 330     }
 331 
 332     /**
 333      * Special-case case version of {@link LambdaMetafactory#metafactory(MethodHandles.Lookup, String, Class, MethodType, MethodHandle, MethodType)}
 334      * that is restricted to non-capturing lambdas.  Rather than returning a
 335      * {@link CallSite}, the function object itself is returned.
 336      * Typically used as a <em>bootstrap method</em> for {@code Dynamic}
 337      * constants, to support the <em>lambda expression</em> and <em>method
 338      * reference expression</em> features of the Java Programming Language.
 339      *
 340      * <p>The function object returned is an instance of a class which
 341      * implements the interface named by {@code functionalInterface},
 342      * declares a method with the name given by {@code invokedName} and the
 343      * signature given by {@code samMethodType}.  It may also override additional
 344      * methods from {@code Object}.
 345      *
 346      * @param caller Represents a lookup context with the accessibility
 347      *               privileges of the caller.  When used with {@code invokedynamic},
 348      *               this is stacked automatically by the VM.
 349      * @param invokedName The name of the method to implement.  When used with
 350      *                    {@code Dynamic} constants, this is provided by the
 351      *                    {@code NameAndType} of the {@code InvokeDynamic}
 352      *                    structure and is stacked automatically by the VM.
 353      * @param functionalInterface The functional interface the function object
 354      *                            should implement.  When used with {@code invokedynamic},
 355      *                            this is provided by the {@code NameAndType} of
 356      *                            the {@code InvokeDynamic} structure and is
 357      *                            stacked automatically by the VM. In the event
 358      *                            that the implementation method is an instance
 359      *                            method and this signature has any parameters,
 360      *                            the first parameter in the invocation signature
 361      *                            must correspond to the receiver.
 362      * @param samMethodType Signature and return type of method to be implemented
 363      *                      by the function object.
 364      * @param implMethod A direct method handle describing the implementation
 365      *                   method which should be called (with suitable adaptation
 366      *                   of argument types, return types, and with captured
 367      *                   arguments prepended to the invocation arguments) at
 368      *                   invocation time.
 369      * @param instantiatedMethodType The signature and return type that should
 370      *                               be enforced dynamically at invocation time.
 371      *                               This may be the same as {@code samMethodType},
 372      *                               or may be a specialization of it.
 373      * @return a CallSite whose target can be used to perform capture, generating
 374      *         instances of the interface named by {@code invokedType}
 375      * @throws LambdaConversionException If any of the linkage invariants
 376      *                                   described {@link LambdaMetafactory above}
 377      *                                   are violated
 378      */
 379     public static Object metafactory(MethodHandles.Lookup caller,
 380                                      String invokedName,
 381                                      Class<?> functionalInterface,
 382                                      MethodType samMethodType,
 383                                      MethodHandle implMethod,
 384                                      MethodType instantiatedMethodType)
 385             throws LambdaConversionException {
 386         AbstractValidatingLambdaMetafactory mf;
 387         mf = new InnerClassLambdaMetafactory(caller, MethodType.methodType(functionalInterface),
 388                                              invokedName, samMethodType,
 389                                              implMethod, instantiatedMethodType,
 390                                              false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
 391         mf.validateMetafactoryArgs();
 392         return mf.buildFunctionalInterfaceInstance();
 393     }
 394 
 395     // @@@ Special case version of altMetafactory, supporting FLAG_METHODREF
 396 
 397     /**
 398      * Facilitates the creation of simple "function objects" that implement one
 399      * or more interfaces by delegation to a provided {@link MethodHandle},
 400      * after appropriate type adaptation and partial evaluation of arguments.
 401      * Typically used as a <em>bootstrap method</em> for {@code invokedynamic}
 402      * call sites, to support the <em>lambda expression</em> and <em>method
 403      * reference expression</em> features of the Java Programming Language.
 404      *
 405      * <p>This is the general, more flexible metafactory; a streamlined version
 406      * is provided by {@link #metafactory(java.lang.invoke.MethodHandles.Lookup,
 407      * String, MethodType, MethodType, MethodHandle, MethodType)}.
 408      * A general description of the behavior of this method is provided
 409      * {@link LambdaMetafactory above}.
 410      *
 411      * <p>The argument list for this method includes three fixed parameters,
 412      * corresponding to the parameters automatically stacked by the VM for the
 413      * bootstrap method in an {@code invokedynamic} invocation, and an {@code Object[]}
 414      * parameter that contains additional parameters.  The declared argument
 415      * list for this method is:
 416      *
 417      * <pre>{@code


 550         boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);
 551         if (isSerializable) {
 552             boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType());
 553             for (Class<?> c : markerInterfaces)
 554                 foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
 555             if (!foundSerializableSupertype) {
 556                 markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
 557                 markerInterfaces[markerInterfaces.length-1] = Serializable.class;
 558             }
 559         }
 560 
 561         AbstractValidatingLambdaMetafactory mf
 562                 = new InnerClassLambdaMetafactory(caller, invokedType,
 563                                                   invokedName, samMethodType,
 564                                                   implMethod,
 565                                                   instantiatedMethodType,
 566                                                   isSerializable,
 567                                                   markerInterfaces, bridges);
 568         mf.validateMetafactoryArgs();
 569         return mf.buildCallSite();
 570     }
 571 
 572     /**
 573      * Special-case case version of {@link LambdaMetafactory#altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}.
 574      * Rather than returning a {@link CallSite}, the function object itself is returned.
 575      * Typically used as a <em>bootstrap method</em> for {@code Dynamic}
 576      * constants, to support the <em>lambda expression</em> and <em>method
 577      * reference expression</em> features of the Java Programming Language.
 578      *
 579      * <p>The function object returned is an instance of a class which
 580      * implements the interface named by {@code functionalInterface},
 581      * declares a method with the name given by {@code invokedName} and the
 582      * signature given by {@code samMethodType}.  It may also override additional
 583      * methods from {@code Object}.
 584      *
 585      * @param caller              Represents a lookup context with the accessibility
 586      *                            privileges of the caller.  When used with {@code invokedynamic},
 587      *                            this is stacked automatically by the VM.
 588      * @param invokedName         The name of the method to implement.  When used with
 589      *                            {@code Dynamic} constants, this is provided by the
 590      *                            {@code NameAndType} of the {@code InvokeDynamic}
 591      *                            structure and is stacked automatically by the VM.
 592      * @param functionalInterface The functional interface the function object
 593      *                            should implement.  When used with {@code invokedynamic},
 594      *                            this is provided by the {@code NameAndType} of
 595      *                            the {@code InvokeDynamic} structure and is
 596      *                            stacked automatically by the VM. In the event
 597      *                            that the implementation method is an instance
 598      *                            method and this signature has any parameters,
 599      *                            the first parameter in the invocation signature
 600      *                            must correspond to the receiver.
 601      * @param args                An {@code Object[]} array containing the required
 602      *                            arguments {@code samMethodType}, {@code implMethod},
 603      *                            {@code instantiatedMethodType}, {@code flags}, and any
 604      *                            optional arguments, as described
 605      *                            {@link #altMetafactory(MethodHandles.Lookup, String, functionalInterface, Object...)} above}
 606      * @return a function object which is an instance of a class which implements the interface named
 607      *         by {@code functionalInterface}
 608      * @throws LambdaConversionException If any of the linkage invariants
 609      *                                   described {@link LambdaMetafactory above}
 610      *                                   are violated
 611      */
 612     public static Object altMetafactory(MethodHandles.Lookup caller,
 613                                           String invokedName,
 614                                           Class<?> functionalInterface,
 615                                           Object... args)
 616             throws LambdaConversionException {
 617         try {
 618             return altMetafactory(caller, invokedName,
 619                     MethodType.methodType(functionalInterface), args).getTarget().invoke();
 620         }
 621         catch (LambdaConversionException | LinkageError e) {
 622             throw e;
 623         }
 624         catch (Throwable e) {
 625             throw new LambdaConversionException("Exception invoking lambda metafactory", e);
 626         }
 627     }
 628 }
< prev index next >