< prev index next >

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

Print this page




 869      * by a single array parameter of type {@code arrayType}.
 870      * <p>
 871      * If the array element type differs from any of the corresponding
 872      * argument types on the original target,
 873      * the original target is adapted to take the array elements directly,
 874      * as if by a call to {@link #asType asType}.
 875      * <p>
 876      * When called, the adapter replaces a trailing array argument
 877      * by the array's elements, each as its own argument to the target.
 878      * (The order of the arguments is preserved.)
 879      * They are converted pairwise by casting and/or unboxing
 880      * to the types of the trailing parameters of the target.
 881      * Finally the target is called.
 882      * What the target eventually returns is returned unchanged by the adapter.
 883      * <p>
 884      * Before calling the target, the adapter verifies that the array
 885      * contains exactly enough elements to provide a correct argument count
 886      * to the target method handle.
 887      * (The array may also be null when zero elements are required.)
 888      * <p>
 889      * If, when the adapter is called, the supplied array argument does
 890      * not have the correct number of elements, the adapter will throw
 891      * an {@link IllegalArgumentException} instead of invoking the target.




 892      * <p>
 893      * Here are some simple examples of array-spreading method handles:
 894      * <blockquote><pre>{@code
 895 MethodHandle equals = publicLookup()
 896   .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
 897 assert( (boolean) equals.invokeExact("me", (Object)"me"));
 898 assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
 899 // spread both arguments from a 2-array:
 900 MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
 901 assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
 902 assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
 903 // try to spread from anything but a 2-array:
 904 for (int n = 0; n <= 10; n++) {
 905   Object[] badArityArgs = (n == 2 ? null : new Object[n]);
 906   try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
 907   catch (IllegalArgumentException ex) { } // OK
 908 }
 909 // spread both arguments from a String array:
 910 MethodHandle eq2s = equals.asSpreader(String[].class, 2);
 911 assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));




 869      * by a single array parameter of type {@code arrayType}.
 870      * <p>
 871      * If the array element type differs from any of the corresponding
 872      * argument types on the original target,
 873      * the original target is adapted to take the array elements directly,
 874      * as if by a call to {@link #asType asType}.
 875      * <p>
 876      * When called, the adapter replaces a trailing array argument
 877      * by the array's elements, each as its own argument to the target.
 878      * (The order of the arguments is preserved.)
 879      * They are converted pairwise by casting and/or unboxing
 880      * to the types of the trailing parameters of the target.
 881      * Finally the target is called.
 882      * What the target eventually returns is returned unchanged by the adapter.
 883      * <p>
 884      * Before calling the target, the adapter verifies that the array
 885      * contains exactly enough elements to provide a correct argument count
 886      * to the target method handle.
 887      * (The array may also be null when zero elements are required.)
 888      * <p>
 889      * When the adapter is called, the length of the supplied {@code array}
 890      * argument is queried as if by {@code array.length} or {@code arraylength}
 891      * bytecode. If the adapter accepts a zero-length trailing array argument,
 892      * the supplied {@code array} argument can either be a zero-length array or
 893      * {@code null}; otherwise, the adapter will throw a {@code NullPointerException}
 894      * if the array is {@code null} and throw an {@link IllegalArgumentException}
 895      * if the array does not have the correct number of elements.
 896      * <p>
 897      * Here are some simple examples of array-spreading method handles:
 898      * <blockquote><pre>{@code
 899 MethodHandle equals = publicLookup()
 900   .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
 901 assert( (boolean) equals.invokeExact("me", (Object)"me"));
 902 assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
 903 // spread both arguments from a 2-array:
 904 MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
 905 assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
 906 assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
 907 // try to spread from anything but a 2-array:
 908 for (int n = 0; n <= 10; n++) {
 909   Object[] badArityArgs = (n == 2 ? null : new Object[n]);
 910   try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
 911   catch (IllegalArgumentException ex) { } // OK
 912 }
 913 // spread both arguments from a String array:
 914 MethodHandle eq2s = equals.asSpreader(String[].class, 2);
 915 assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));


< prev index next >