8001109: arity mismatch on a call to spreader method handle should elicit IllegalArgumentException
Document error conditions that may occur when calling a "spreader" method handle. Use IAE in all cases. Reviewed-by: twisti, vlivanov
This commit is contained in:
parent
77dc59f6ca
commit
e4df9dc1ee
jdk
src/share/classes/java/lang/invoke
test/java/lang/invoke
@ -804,6 +804,10 @@ public abstract class MethodHandle {
|
|||||||
* to the target method handle.
|
* to the target method handle.
|
||||||
* (The array may also be null when zero elements are required.)
|
* (The array may also be null when zero elements are required.)
|
||||||
* <p>
|
* <p>
|
||||||
|
* If, when the adapter is called, the supplied array argument does
|
||||||
|
* not have the correct number of elements, the adapter will throw
|
||||||
|
* an {@link IllegalArgumentException} instead of invoking the target.
|
||||||
|
* <p>
|
||||||
* Here are some simple examples of array-spreading method handles:
|
* Here are some simple examples of array-spreading method handles:
|
||||||
* <blockquote><pre>{@code
|
* <blockquote><pre>{@code
|
||||||
MethodHandle equals = publicLookup()
|
MethodHandle equals = publicLookup()
|
||||||
@ -814,6 +818,12 @@ assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
|
|||||||
MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
|
MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
|
||||||
assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
|
assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
|
||||||
assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
|
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 ? null : new Object[n]);
|
||||||
|
try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
|
||||||
|
catch (IllegalArgumentException ex) { } // OK
|
||||||
|
}
|
||||||
// spread both arguments from a String array:
|
// spread both arguments from a String array:
|
||||||
MethodHandle eq2s = equals.asSpreader(String[].class, 2);
|
MethodHandle eq2s = equals.asSpreader(String[].class, 2);
|
||||||
assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
|
assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
|
||||||
|
@ -460,14 +460,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void checkSpreadArgument(Object av, int n) {
|
static void checkSpreadArgument(Object av, int n) {
|
||||||
// FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
|
|
||||||
// but the actual exception raised by an arity mismatch should be WMTE
|
|
||||||
final boolean RAISE_RANDOM_EXCEPTIONS = true; // FIXME: delete in JSR 292 M1
|
|
||||||
if (av == null) {
|
if (av == null) {
|
||||||
if (n == 0) return;
|
if (n == 0) return;
|
||||||
int len;
|
|
||||||
if (RAISE_RANDOM_EXCEPTIONS)
|
|
||||||
len = ((Object[])av).length; // throw NPE; but delete this after tests are fixed
|
|
||||||
} else if (av instanceof Object[]) {
|
} else if (av instanceof Object[]) {
|
||||||
int len = ((Object[])av).length;
|
int len = ((Object[])av).length;
|
||||||
if (len == n) return;
|
if (len == n) return;
|
||||||
@ -476,9 +470,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
|||||||
if (len == n) return;
|
if (len == n) return;
|
||||||
}
|
}
|
||||||
// fall through to error:
|
// fall through to error:
|
||||||
if (RAISE_RANDOM_EXCEPTIONS)
|
throw newIllegalArgumentException("array is not of length "+n);
|
||||||
throw newIllegalArgumentException("Array is not of length "+n);
|
|
||||||
throw new WrongMethodTypeException("Array is not of length "+n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1511,6 +1511,9 @@ return mh1;
|
|||||||
* <p>
|
* <p>
|
||||||
* Before invoking its target, the invoker will spread the final array, apply
|
* Before invoking its target, the invoker will spread the final array, apply
|
||||||
* reference casts as necessary, and unbox and widen primitive arguments.
|
* reference casts as necessary, and unbox and widen primitive arguments.
|
||||||
|
* If, when the invoker is called, the supplied array argument does
|
||||||
|
* not have the correct number of elements, the invoker will throw
|
||||||
|
* an {@link IllegalArgumentException} instead of invoking the target.
|
||||||
* <p>
|
* <p>
|
||||||
* This method is equivalent to the following code (though it may be more efficient):
|
* This method is equivalent to the following code (though it may be more efficient):
|
||||||
* <p><blockquote><pre>
|
* <p><blockquote><pre>
|
||||||
|
@ -264,6 +264,12 @@ assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
|
|||||||
MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
|
MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
|
||||||
assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
|
assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
|
||||||
assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
|
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 ? null : new Object[n]);
|
||||||
|
try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
|
||||||
|
catch (IllegalArgumentException ex) { } // OK
|
||||||
|
}
|
||||||
// spread both arguments from a String array:
|
// spread both arguments from a String array:
|
||||||
MethodHandle eq2s = equals.asSpreader(String[].class, 2);
|
MethodHandle eq2s = equals.asSpreader(String[].class, 2);
|
||||||
assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
|
assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user