Share via


MethodHandle.AsSpreader Method

Definition

Overloads

AsSpreader(Class, Int32)

Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument and spreads its elements as positional arguments.

AsSpreader(Int32, Class, Int32)

Makes an <em>array-spreading</em> method handle, which accepts an array argument at a given position and spreads its elements as positional arguments in place of the array.

AsSpreader(Class, Int32)

Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument and spreads its elements as positional arguments.

[Android.Runtime.Register("asSpreader", "(Ljava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_Ljava_lang_Class_IHandler", ApiSince=26)]
public virtual Java.Lang.Invoke.MethodHandle? AsSpreader (Java.Lang.Class? arrayType, int arrayLength);
[<Android.Runtime.Register("asSpreader", "(Ljava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_Ljava_lang_Class_IHandler", ApiSince=26)>]
abstract member AsSpreader : Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle
override this.AsSpreader : Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle

Parameters

arrayType
Class

usually Object[], the type of the array argument from which to extract the spread arguments

arrayLength
Int32

the number of arguments to spread from an incoming array argument

Returns

a new method handle which spreads its final array argument, before calling the original method handle

Attributes

Remarks

Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument and spreads its elements as positional arguments. The new method handle adapts, as its target, the current method handle. The type of the adapter will be the same as the type of the target, except that the final arrayLength parameters of the target's type are replaced by a single array parameter of type arrayType.

If the array element type differs from any of the corresponding argument types on the original target, the original target is adapted to take the array elements directly, as if by a call to #asType asType.

When called, the adapter replaces a trailing array argument by the array's elements, each as its own argument to the target. (The order of the arguments is preserved.) They are converted pairwise by casting and/or unboxing to the types of the trailing parameters of the target. Finally the target is called. What the target eventually returns is returned unchanged by the adapter.

Before calling the target, the adapter verifies that the array contains exactly enough elements to provide a correct argument count to the target method handle. (The array may also be null when zero elements are required.)

When the adapter is called, the length of the supplied array argument is queried as if by array.length or arraylength bytecode. If the adapter accepts a zero-length trailing array argument, the supplied array argument can either be a zero-length array or null; otherwise, the adapter will throw a NullPointerException if the array is null and throw an IllegalArgumentException if the array does not have the correct number of elements.

Here are some simple examples of array-spreading method handles: <blockquote>

{@code
            MethodHandle equals = publicLookup()
              .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
            assert( (boolean) equals.invokeExact("me", (Object)"me"));
            assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
            // spread both arguments from a 2-array:
            MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
            assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
            assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
            // try to spread from anything but a 2-array:
            for (int n = 0; n <= 10; n++) {
              Object[] badArityArgs = (n == 2 ? new Object[0] : new Object[n]);
              try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
              catch (IllegalArgumentException ex) { } // OK
            }
            // spread both arguments from a String array:
            MethodHandle eq2s = equals.asSpreader(String[].class, 2);
            assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
            assert(!(boolean) eq2s.invokeExact(new String[]{ "me", "thee" }));
            // spread second arguments from a 1-array:
            MethodHandle eq1 = equals.asSpreader(Object[].class, 1);
            assert( (boolean) eq1.invokeExact("me", new Object[]{ "me" }));
            assert(!(boolean) eq1.invokeExact("me", new Object[]{ "thee" }));
            // spread no arguments from a 0-array or null:
            MethodHandle eq0 = equals.asSpreader(Object[].class, 0);
            assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));
            assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));
            // asSpreader and asCollector are approximate inverses:
            for (int n = 0; n <= 2; n++) {
                for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {
                    MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);
                    assert( (boolean) equals2.invokeWithArguments("me", "me"));
                    assert(!(boolean) equals2.invokeWithArguments("me", "thee"));
                }
            }
            MethodHandle caToString = publicLookup()
              .findStatic(Arrays.class, "toString", methodType(String.class, char[].class));
            assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
            MethodHandle caString3 = caToString.asCollector(char[].class, 3);
            assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
            MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
            assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
            }

</blockquote>

Java documentation for java.lang.invoke.MethodHandle.asSpreader(java.lang.Class<?>, int).

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

Applies to

AsSpreader(Int32, Class, Int32)

Makes an <em>array-spreading</em> method handle, which accepts an array argument at a given position and spreads its elements as positional arguments in place of the array.

[Android.Runtime.Register("asSpreader", "(ILjava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_ILjava_lang_Class_IHandler", ApiSince=33)]
public virtual Java.Lang.Invoke.MethodHandle? AsSpreader (int spreadArgPos, Java.Lang.Class? arrayType, int arrayLength);
[<Android.Runtime.Register("asSpreader", "(ILjava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_ILjava_lang_Class_IHandler", ApiSince=33)>]
abstract member AsSpreader : int * Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle
override this.AsSpreader : int * Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle

Parameters

spreadArgPos
Int32

the position (zero-based index) in the argument list at which spreading should start.

arrayType
Class

usually Object[], the type of the array argument from which to extract the spread arguments

arrayLength
Int32

the number of arguments to spread from an incoming array argument

Returns

a new method handle which spreads an array argument at a given position, before calling the original method handle

Attributes

Remarks

Makes an <em>array-spreading</em> method handle, which accepts an array argument at a given position and spreads its elements as positional arguments in place of the array. The new method handle adapts, as its target, the current method handle. The type of the adapter will be the same as the type of the target, except that the arrayLength parameters of the target's type, starting at the zero-based position spreadArgPos, are replaced by a single array parameter of type arrayType.

This method behaves very much like #asSpreader(Class, int), but accepts an additional spreadArgPos argument to indicate at which position in the parameter list the spreading should take place.

Added in 9.

Java documentation for java.lang.invoke.MethodHandle.asSpreader(int, java.lang.Class<?>, int).

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

Applies to