< prev index next >

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

Print this page




3749      *         {@code pos}.
3750      * @since 9
3751      */
3752     public static
3753     MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos) {
3754         Objects.requireNonNull(target);
3755         Objects.requireNonNull(newTypes);
3756         return dropArgumentsToMatch(target, skip, newTypes, pos, false);
3757     }
3758 
3759     /**
3760      * Adapts a target method handle by pre-processing
3761      * one or more of its arguments, each with its own unary filter function,
3762      * and then calling the target with each pre-processed argument
3763      * replaced by the result of its corresponding filter function.
3764      * <p>
3765      * The pre-processing is performed by one or more method handles,
3766      * specified in the elements of the {@code filters} array.
3767      * The first element of the filter array corresponds to the {@code pos}
3768      * argument of the target, and so on in sequence.

3769      * <p>
3770      * Null arguments in the array are treated as identity functions,
3771      * and the corresponding arguments left unchanged.
3772      * (If there are no non-null elements in the array, the original target is returned.)
3773      * Each filter is applied to the corresponding argument of the adapter.
3774      * <p>
3775      * If a filter {@code F} applies to the {@code N}th argument of
3776      * the target, then {@code F} must be a method handle which
3777      * takes exactly one argument.  The type of {@code F}'s sole argument
3778      * replaces the corresponding argument type of the target
3779      * in the resulting adapted method handle.
3780      * The return type of {@code F} must be identical to the corresponding
3781      * parameter type of the target.
3782      * <p>
3783      * It is an error if there are elements of {@code filters}
3784      * (null or not)
3785      * which do not correspond to argument positions in the target.
3786      * <p><b>Example:</b>
3787      * <blockquote><pre>{@code
3788 import static java.lang.invoke.MethodHandles.*;


3819      * <p>
3820      * <em>Note:</em> The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
3821      * variable-arity method handle}, even if the original target method handle was.
3822      *
3823      * @param target the method handle to invoke after arguments are filtered
3824      * @param pos the position of the first argument to filter
3825      * @param filters method handles to call initially on filtered arguments
3826      * @return method handle which incorporates the specified argument filtering logic
3827      * @throws NullPointerException if the target is null
3828      *                              or if the {@code filters} array is null
3829      * @throws IllegalArgumentException if a non-null element of {@code filters}
3830      *          does not match a corresponding argument type of target as described above,
3831      *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
3832      *          or if the resulting method handle's type would have
3833      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
3834      */
3835     public static
3836     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
3837         filterArgumentsCheckArity(target, pos, filters);
3838         MethodHandle adapter = target;
3839         int curPos = pos-1;  // pre-incremented
3840         for (MethodHandle filter : filters) {
3841             curPos += 1;

3842             if (filter == null)  continue;  // ignore null elements of filters
3843             adapter = filterArgument(adapter, curPos, filter);
3844         }
3845         return adapter;
3846     }
3847 
3848     /*non-public*/ static
3849     MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
3850         filterArgumentChecks(target, pos, filter);
3851         MethodType targetType = target.type();
3852         MethodType filterType = filter.type();
3853         BoundMethodHandle result = target.rebind();
3854         Class<?> newParamType = filterType.parameterType(0);
3855         LambdaForm lform = result.editor().filterArgumentForm(1 + pos, BasicType.basicType(newParamType));
3856         MethodType newType = targetType.changeParameterType(pos, newParamType);
3857         result = result.copyWithExtendL(newType, lform, filter);
3858         return result;
3859     }
3860 
3861     private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
3862         MethodType targetType = target.type();
3863         int maxPos = targetType.parameterCount();




3749      *         {@code pos}.
3750      * @since 9
3751      */
3752     public static
3753     MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos) {
3754         Objects.requireNonNull(target);
3755         Objects.requireNonNull(newTypes);
3756         return dropArgumentsToMatch(target, skip, newTypes, pos, false);
3757     }
3758 
3759     /**
3760      * Adapts a target method handle by pre-processing
3761      * one or more of its arguments, each with its own unary filter function,
3762      * and then calling the target with each pre-processed argument
3763      * replaced by the result of its corresponding filter function.
3764      * <p>
3765      * The pre-processing is performed by one or more method handles,
3766      * specified in the elements of the {@code filters} array.
3767      * The first element of the filter array corresponds to the {@code pos}
3768      * argument of the target, and so on in sequence.
3769      * The filter functions are invoked in left to right order.
3770      * <p>
3771      * Null arguments in the array are treated as identity functions,
3772      * and the corresponding arguments left unchanged.
3773      * (If there are no non-null elements in the array, the original target is returned.)
3774      * Each filter is applied to the corresponding argument of the adapter.
3775      * <p>
3776      * If a filter {@code F} applies to the {@code N}th argument of
3777      * the target, then {@code F} must be a method handle which
3778      * takes exactly one argument.  The type of {@code F}'s sole argument
3779      * replaces the corresponding argument type of the target
3780      * in the resulting adapted method handle.
3781      * The return type of {@code F} must be identical to the corresponding
3782      * parameter type of the target.
3783      * <p>
3784      * It is an error if there are elements of {@code filters}
3785      * (null or not)
3786      * which do not correspond to argument positions in the target.
3787      * <p><b>Example:</b>
3788      * <blockquote><pre>{@code
3789 import static java.lang.invoke.MethodHandles.*;


3820      * <p>
3821      * <em>Note:</em> The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
3822      * variable-arity method handle}, even if the original target method handle was.
3823      *
3824      * @param target the method handle to invoke after arguments are filtered
3825      * @param pos the position of the first argument to filter
3826      * @param filters method handles to call initially on filtered arguments
3827      * @return method handle which incorporates the specified argument filtering logic
3828      * @throws NullPointerException if the target is null
3829      *                              or if the {@code filters} array is null
3830      * @throws IllegalArgumentException if a non-null element of {@code filters}
3831      *          does not match a corresponding argument type of target as described above,
3832      *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
3833      *          or if the resulting method handle's type would have
3834      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
3835      */
3836     public static
3837     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
3838         filterArgumentsCheckArity(target, pos, filters);
3839         MethodHandle adapter = target;
3840         // process filters in reverse order so that the invocation of
3841         // the resulting adapter will invoke the filters in left-to-right order
3842         for (int i = filters.length - 1; i >= 0; --i) {
3843             MethodHandle filter = filters[i];
3844             if (filter == null)  continue;  // ignore null elements of filters
3845             adapter = filterArgument(adapter, pos + i, filter);
3846         }
3847         return adapter;
3848     }
3849 
3850     /*non-public*/ static
3851     MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
3852         filterArgumentChecks(target, pos, filter);
3853         MethodType targetType = target.type();
3854         MethodType filterType = filter.type();
3855         BoundMethodHandle result = target.rebind();
3856         Class<?> newParamType = filterType.parameterType(0);
3857         LambdaForm lform = result.editor().filterArgumentForm(1 + pos, BasicType.basicType(newParamType));
3858         MethodType newType = targetType.changeParameterType(pos, newParamType);
3859         result = result.copyWithExtendL(newType, lform, filter);
3860         return result;
3861     }
3862 
3863     private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
3864         MethodType targetType = target.type();
3865         int maxPos = targetType.parameterCount();


< prev index next >