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" })); |