< prev index next >

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

Print this page




   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
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 

  29 import java.util.*;
  30 
  31 import static java.lang.invoke.MethodHandleStatics.*;
  32 
  33 /**
  34  * A method handle is a typed, directly executable reference to an underlying method,
  35  * constructor, field, or similar low-level operation, with optional
  36  * transformations of arguments or return values.
  37  * These transformations are quite general, and include such patterns as
  38  * {@linkplain #asType conversion},
  39  * {@linkplain #bindTo insertion},
  40  * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
  41  * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
  42  *
  43  * <h1>Method handle contents</h1>
  44  * Method handles are dynamically and strongly typed according to their parameter and return types.
  45  * They are not distinguished by the name or the defining class of their underlying methods.
  46  * A method handle must be invoked using a symbolic type descriptor which matches
  47  * the method handle's own {@linkplain #type type descriptor}.
  48  * <p>


 415  * In particular, a method handle&rsquo;s type must not have an arity of the exact maximum 255.
 416  *
 417  * @see MethodType
 418  * @see MethodHandles
 419  * @author John Rose, JSR 292 EG
 420  */
 421 public abstract class MethodHandle {
 422     static { MethodHandleImpl.initStatics(); }
 423 
 424     /**
 425      * Internal marker interface which distinguishes (to the Java compiler)
 426      * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
 427      */
 428     @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
 429     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
 430     @interface PolymorphicSignature { }
 431 
 432     private final MethodType type;
 433     /*private*/ final LambdaForm form;
 434     // form is not private so that invokers can easily fetch it
 435     /*private*/ MethodHandle asTypeCache;
 436     // asTypeCache is not private so that invokers can easily fetch it
 437     /*non-public*/ byte customizationCount;
 438     // customizationCount should be accessible from invokers
 439 
 440     /**
 441      * Reports the type of this method handle.
 442      * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
 443      * @return the method handle type
 444      */
 445     public MethodType type() {
 446         return type;
 447     }
 448 
 449     /**
 450      * Package-private constructor for the method handle implementation hierarchy.
 451      * Method handle inheritance will be contained completely within
 452      * the {@code java.lang.invoke} package.
 453      */
 454     // @param type type (permanently assigned) of the new method handle
 455     /*non-public*/ MethodHandle(MethodType type, LambdaForm form) {
 456         this.type = Objects.requireNonNull(type);


 728      * pairwise conversions cannot be made.
 729      * <p>
 730      * At runtime, the conversions applied to reference arguments
 731      * or return values may require additional runtime checks which can fail.
 732      * An unboxing operation may fail because the original reference is null,
 733      * causing a {@link java.lang.NullPointerException NullPointerException}.
 734      * An unboxing operation or a reference cast may also fail on a reference
 735      * to an object of the wrong type,
 736      * causing a {@link java.lang.ClassCastException ClassCastException}.
 737      * Although an unboxing operation may accept several kinds of wrappers,
 738      * if none are available, a {@code ClassCastException} will be thrown.
 739      *
 740      * @param newType the expected type of the new method handle
 741      * @return a method handle which delegates to {@code this} after performing
 742      *           any necessary argument conversions, and arranges for any
 743      *           necessary return value conversions
 744      * @throws NullPointerException if {@code newType} is a null reference
 745      * @throws WrongMethodTypeException if the conversion cannot be made
 746      * @see MethodHandles#explicitCastArguments
 747      */
 748     public MethodHandle asType(MethodType newType) {
 749         // Fast path alternative to a heavyweight {@code asType} call.
 750         // Return 'this' if the conversion will be a no-op.
 751         if (newType == type) {
 752             return this;
 753         }
 754         // Return 'this.asTypeCache' if the conversion is already memoized.
 755         MethodHandle atc = asTypeCached(newType);
 756         if (atc != null) {
 757             return atc;
 758         }
 759         return asTypeUncached(newType);


 760     }
 761 
 762     private MethodHandle asTypeCached(MethodType newType) {
 763         MethodHandle atc = asTypeCache;
 764         if (atc != null && newType == atc.type) {

 765             return atc;
 766         }
 767         return null;
 768     }
 769 
 770     /** Override this to change asType behavior. */
 771     /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
 772         if (!type.isConvertibleTo(newType))
 773             throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
 774         return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
 775     }
 776 
 777     /**
 778      * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
 779      * and spreads its elements as positional arguments.
 780      * The new method handle adapts, as its <i>target</i>,
 781      * the current method handle.  The type of the adapter will be
 782      * the same as the type of the target, except that the final
 783      * {@code arrayLength} parameters of the target's type are replaced
 784      * by a single array parameter of type {@code arrayType}.
 785      * <p>
 786      * If the array element type differs from any of the corresponding
 787      * argument types on the original target,
 788      * the original target is adapted to take the array elements directly,
 789      * as if by a call to {@link #asType asType}.
 790      * <p>
 791      * When called, the adapter replaces a trailing array argument
 792      * by the array's elements, each as its own argument to the target.
 793      * (The order of the arguments is preserved.)
 794      * They are converted pairwise by casting and/or unboxing




   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
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 
  29 import java.lang.ref.WeakReference;
  30 import java.util.*;
  31 
  32 import static java.lang.invoke.MethodHandleStatics.*;
  33 
  34 /**
  35  * A method handle is a typed, directly executable reference to an underlying method,
  36  * constructor, field, or similar low-level operation, with optional
  37  * transformations of arguments or return values.
  38  * These transformations are quite general, and include such patterns as
  39  * {@linkplain #asType conversion},
  40  * {@linkplain #bindTo insertion},
  41  * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
  42  * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
  43  *
  44  * <h1>Method handle contents</h1>
  45  * Method handles are dynamically and strongly typed according to their parameter and return types.
  46  * They are not distinguished by the name or the defining class of their underlying methods.
  47  * A method handle must be invoked using a symbolic type descriptor which matches
  48  * the method handle's own {@linkplain #type type descriptor}.
  49  * <p>


 416  * In particular, a method handle&rsquo;s type must not have an arity of the exact maximum 255.
 417  *
 418  * @see MethodType
 419  * @see MethodHandles
 420  * @author John Rose, JSR 292 EG
 421  */
 422 public abstract class MethodHandle {
 423     static { MethodHandleImpl.initStatics(); }
 424 
 425     /**
 426      * Internal marker interface which distinguishes (to the Java compiler)
 427      * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
 428      */
 429     @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
 430     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
 431     @interface PolymorphicSignature { }
 432 
 433     private final MethodType type;
 434     /*private*/ final LambdaForm form;
 435     // form is not private so that invokers can easily fetch it
 436     private WeakReference<MethodHandle> asTypeCache;

 437     /*non-public*/ byte customizationCount;
 438     // customizationCount should be accessible from invokers
 439 
 440     /**
 441      * Reports the type of this method handle.
 442      * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
 443      * @return the method handle type
 444      */
 445     public MethodType type() {
 446         return type;
 447     }
 448 
 449     /**
 450      * Package-private constructor for the method handle implementation hierarchy.
 451      * Method handle inheritance will be contained completely within
 452      * the {@code java.lang.invoke} package.
 453      */
 454     // @param type type (permanently assigned) of the new method handle
 455     /*non-public*/ MethodHandle(MethodType type, LambdaForm form) {
 456         this.type = Objects.requireNonNull(type);


 728      * pairwise conversions cannot be made.
 729      * <p>
 730      * At runtime, the conversions applied to reference arguments
 731      * or return values may require additional runtime checks which can fail.
 732      * An unboxing operation may fail because the original reference is null,
 733      * causing a {@link java.lang.NullPointerException NullPointerException}.
 734      * An unboxing operation or a reference cast may also fail on a reference
 735      * to an object of the wrong type,
 736      * causing a {@link java.lang.ClassCastException ClassCastException}.
 737      * Although an unboxing operation may accept several kinds of wrappers,
 738      * if none are available, a {@code ClassCastException} will be thrown.
 739      *
 740      * @param newType the expected type of the new method handle
 741      * @return a method handle which delegates to {@code this} after performing
 742      *           any necessary argument conversions, and arranges for any
 743      *           necessary return value conversions
 744      * @throws NullPointerException if {@code newType} is a null reference
 745      * @throws WrongMethodTypeException if the conversion cannot be made
 746      * @see MethodHandles#explicitCastArguments
 747      */
 748     public final MethodHandle asType(MethodType newType) {
 749         // Fast path alternative to a heavyweight {@code asType} call.
 750         // Return 'this' if the conversion will be a no-op.
 751         if (newType == type) {
 752             return this;
 753         }
 754         // Return 'this.asTypeCache' if the conversion is already memoized.
 755         MethodHandle at = asTypeCached(newType);
 756         if (at != null) {
 757             return at;
 758         }
 759         at = asTypeUncached(newType);
 760         asTypeCache = new WeakReference<>(at);
 761         return at;
 762     }
 763 
 764     private MethodHandle asTypeCached(MethodType newType) {
 765         MethodHandle atc;
 766         if (asTypeCache != null && (atc = asTypeCache.get()) != null &&
 767                 newType == atc.type) {
 768             return atc;
 769         }
 770         return null;
 771     }
 772 
 773     /** Override this to change asType behavior. */
 774     /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
 775         if (!type.isConvertibleTo(newType))
 776             throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
 777         return MethodHandleImpl.makePairwiseConvert(this, newType, true);
 778     }
 779 
 780     /**
 781      * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
 782      * and spreads its elements as positional arguments.
 783      * The new method handle adapts, as its <i>target</i>,
 784      * the current method handle.  The type of the adapter will be
 785      * the same as the type of the target, except that the final
 786      * {@code arrayLength} parameters of the target's type are replaced
 787      * by a single array parameter of type {@code arrayType}.
 788      * <p>
 789      * If the array element type differs from any of the corresponding
 790      * argument types on the original target,
 791      * the original target is adapted to take the array elements directly,
 792      * as if by a call to {@link #asType asType}.
 793      * <p>
 794      * When called, the adapter replaces a trailing array argument
 795      * by the array's elements, each as its own argument to the target.
 796      * (The order of the arguments is preserved.)
 797      * They are converted pairwise by casting and/or unboxing


< prev index next >