198 * This is done via a reflective, capability-based API called
199 * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
200 * For example, a static method handle can be obtained
201 * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
202 * There are also conversion methods from Core Reflection API objects,
203 * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
204 * <p>
205 * Like classes and strings, method handles that correspond to accessible
206 * fields, methods, and constructors can also be represented directly
207 * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
208 * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
209 * refers directly to an associated {@code CONSTANT_Methodref},
210 * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
211 * constant pool entry.
212 * (For full details on method handle constants,
213 * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
214 * <p>
215 * Method handles produced by lookups or constant loads from methods or
216 * constructors with the variable arity modifier bit ({@code 0x0080})
217 * have a corresponding variable arity, as if they were defined with
218 * the help of {@link #asVarargsCollector asVarargsCollector}.
219 * <p>
220 * A method reference may refer either to a static or non-static method.
221 * In the non-static case, the method handle type includes an explicit
222 * receiver argument, prepended before any other arguments.
223 * In the method handle's type, the initial receiver argument is typed
224 * according to the class under which the method was initially requested.
225 * (E.g., if a non-static method handle is obtained via {@code ldc},
226 * the type of the receiver is the class named in the constant pool entry.)
227 * <p>
228 * Method handle constants are subject to the same link-time access checks
229 * their corresponding bytecode instructions, and the {@code ldc} instruction
230 * will throw corresponding linkage errors if the bytecode behaviors would
231 * throw such errors.
232 * <p>
233 * As a corollary of this, access to protected members is restricted
234 * to receivers only of the accessing class, or one of its subclasses,
235 * and the accessing class must in turn be a subclass (or package sibling)
236 * of the protected member's defining class.
237 * If a method reference refers to a protected non-static method or field
238 * of a class outside the current package, the receiver argument will
951 MethodType needType = mtype.asSpreaderType(arrayType, pos, arrayLength);
952 if (!fail) return needType;
953 // elicit an error:
954 this.asType(needType);
955 throw newInternalError("should not return", null);
956 }
957
958 private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
959 Class<?> arrayElement = arrayType.getComponentType();
960 if (arrayElement == null)
961 throw newIllegalArgumentException("not an array type", arrayType);
962 if ((arrayLength & 0x7F) != arrayLength) {
963 if ((arrayLength & 0xFF) != arrayLength)
964 throw newIllegalArgumentException("array length is not legal", arrayLength);
965 assert(arrayLength >= 128);
966 if (arrayElement == long.class ||
967 arrayElement == double.class)
968 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
969 }
970 }
971
972 /**
973 * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
974 * positional arguments and collects them into an array argument.
975 * The new method handle adapts, as its <i>target</i>,
976 * the current method handle. The type of the adapter will be
977 * the same as the type of the target, except that a single trailing
978 * parameter (usually of type {@code arrayType}) is replaced by
979 * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
980 * <p>
981 * If the array type differs from the final argument type on the original target,
982 * the original target is adapted to take the array type directly,
983 * as if by a call to {@link #asType asType}.
984 * <p>
985 * When called, the adapter replaces its trailing {@code arrayLength}
986 * arguments by a single new array of type {@code arrayType}, whose elements
987 * comprise (in order) the replaced arguments.
988 * Finally the target is called.
989 * What the target eventually returns is returned unchanged by the adapter.
990 * <p>
991 * (The array may also be a shared constant when {@code arrayLength} is zero.)
992 * <p>
993 * (<em>Note:</em> The {@code arrayType} is often identical to the last
994 * parameter type of the original target.
995 * It is an explicit argument for symmetry with {@code asSpreader}, and also
996 * to allow the target to use a simple {@code Object} as its last parameter type.)
997 * <p>
998 * In order to create a collecting adapter which is not restricted to a particular
999 * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
1000 * <p>
1001 * Here are some examples of array-collecting method handles:
1002 * <blockquote><pre>{@code
1003 MethodHandle deepToString = publicLookup()
1004 .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
1005 assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));
1006 MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
1007 assertEquals(methodType(String.class, Object.class), ts1.type());
1008 //assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"})); //FAIL
1009 assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"}));
1010 // arrayType can be a subtype of Object[]
1011 MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
1012 assertEquals(methodType(String.class, String.class, String.class), ts2.type());
1013 assertEquals("[two, too]", (String) ts2.invokeExact("two", "too"));
1014 MethodHandle ts0 = deepToString.asCollector(Object[].class, 0);
1015 assertEquals("[]", (String) ts0.invokeExact());
1016 // collectors can be nested, Lisp-style
1017 MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2);
1018 assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D")));
1019 // arrayType can be any primitive array type
1195 * Therefore, a variable arity adapter responds
1196 * to an {@code asType} request by building a fixed arity collector,
1197 * if and only if the adapter and requested type differ either
1198 * in arity or trailing argument type.
1199 * The resulting fixed arity collector has its type further adjusted
1200 * (if necessary) to the requested type by pairwise conversion,
1201 * as if by another application of {@code asType}.
1202 * <p>
1203 * When a method handle is obtained by executing an {@code ldc} instruction
1204 * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
1205 * as a variable arity method (with the modifier bit {@code 0x0080}),
1206 * the method handle will accept multiple arities, as if the method handle
1207 * constant were created by means of a call to {@code asVarargsCollector}.
1208 * <p>
1209 * In order to create a collecting adapter which collects a predetermined
1210 * number of arguments, and whose type reflects this predetermined number,
1211 * use {@link #asCollector asCollector} instead.
1212 * <p>
1213 * No method handle transformations produce new method handles with
1214 * variable arity, unless they are documented as doing so.
1215 * Therefore, besides {@code asVarargsCollector},
1216 * all methods in {@code MethodHandle} and {@code MethodHandles}
1217 * will return a method handle with fixed arity,
1218 * except in the cases where they are specified to return their original
1219 * operand (e.g., {@code asType} of the method handle's own type).
1220 * <p>
1221 * Calling {@code asVarargsCollector} on a method handle which is already
1222 * of variable arity will produce a method handle with the same type and behavior.
1223 * It may (or may not) return the original variable arity method handle.
1224 * <p>
1225 * Here is an example, of a list-making variable arity method handle:
1226 * <blockquote><pre>{@code
1227 MethodHandle deepToString = publicLookup()
1228 .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
1229 MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
1230 assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));
1231 assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));
1232 assertEquals("[won]", (String) ts1.invoke( "won" ));
1233 assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
1234 // findStatic of Arrays.asList(...) produces a variable arity method handle:
1235 MethodHandle asList = publicLookup()
1252 * of the Java rules for variable arity methods.
1253 * In both cases, callers to a variable arity method or method handle
1254 * can either pass zero or more positional arguments, or else pass
1255 * pre-collected arrays of any length. Users should be aware of the
1256 * special role of the final argument, and of the effect of a
1257 * type match on that final argument, which determines whether
1258 * or not a single trailing argument is interpreted as a whole
1259 * array or a single element of an array to be collected.
1260 * Note that the dynamic type of the trailing argument has no
1261 * effect on this decision, only a comparison between the symbolic
1262 * type descriptor of the call site and the type descriptor of the method handle.)
1263 *
1264 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1265 * @return a new method handle which can collect any number of trailing arguments
1266 * into an array, before calling the original method handle
1267 * @throws NullPointerException if {@code arrayType} is a null reference
1268 * @throws IllegalArgumentException if {@code arrayType} is not an array type
1269 * or {@code arrayType} is not assignable to this method handle's trailing parameter type
1270 * @see #asCollector
1271 * @see #isVarargsCollector
1272 * @see #asFixedArity
1273 */
1274 public MethodHandle asVarargsCollector(Class<?> arrayType) {
1275 Objects.requireNonNull(arrayType);
1276 boolean lastMatch = asCollectorChecks(arrayType, type().parameterCount() - 1, 0);
1277 if (isVarargsCollector() && lastMatch)
1278 return this;
1279 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1280 }
1281
1282 /**
1283 * Determines if this method handle
1284 * supports {@linkplain #asVarargsCollector variable arity} calls.
1285 * Such method handles arise from the following sources:
1286 * <ul>
1287 * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
1288 * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
1289 * which resolves to a variable arity Java method or constructor
1290 * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
1291 * which resolves to a variable arity Java method or constructor
1323 MethodHandle asListFix = asListVar.asFixedArity();
1324 assertEquals("[1]", asListVar.invoke(1).toString());
1325 Exception caught = null;
1326 try { asListFix.invoke((Object)1); }
1327 catch (Exception ex) { caught = ex; }
1328 assert(caught instanceof ClassCastException);
1329 assertEquals("[two, too]", asListVar.invoke("two", "too").toString());
1330 try { asListFix.invoke("two", "too"); }
1331 catch (Exception ex) { caught = ex; }
1332 assert(caught instanceof WrongMethodTypeException);
1333 Object[] argv = { "three", "thee", "tee" };
1334 assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
1335 assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString());
1336 assertEquals(1, ((List) asListVar.invoke((Object)argv)).size());
1337 assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
1338 * }</pre></blockquote>
1339 *
1340 * @return a new method handle which accepts only a fixed number of arguments
1341 * @see #asVarargsCollector
1342 * @see #isVarargsCollector
1343 */
1344 public MethodHandle asFixedArity() {
1345 assert(!isVarargsCollector());
1346 return this;
1347 }
1348
1349 /**
1350 * Binds a value {@code x} to the first argument of a method handle, without invoking it.
1351 * The new method handle adapts, as its <i>target</i>,
1352 * the current method handle by binding it to the given argument.
1353 * The type of the bound handle will be
1354 * the same as the type of the target, except that a single leading
1355 * reference parameter will be omitted.
1356 * <p>
1357 * When called, the bound handle inserts the given value {@code x}
1358 * as a new leading argument to the target. The other arguments are
1359 * also passed unchanged.
1360 * What the target eventually returns is returned unchanged by the bound handle.
1361 * <p>
1362 * The reference {@code x} must be convertible to the first parameter
1407 /** Return a string with a several lines describing the method handle structure.
1408 * This string would be suitable for display in an IDE debugger.
1409 */
1410 String debugString() {
1411 return type+" : "+internalForm()+internalProperties();
1412 }
1413
1414 //// Implementation methods.
1415 //// Sub-classes can override these default implementations.
1416 //// All these methods assume arguments are already validated.
1417
1418 // Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
1419
1420 BoundMethodHandle bindArgumentL(int pos, Object value) {
1421 return rebind().bindArgumentL(pos, value);
1422 }
1423
1424 /*non-public*/
1425 MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1426 if (!member.isVarargs()) return this;
1427 Class<?> arrayType = type().lastParameterType();
1428 if (arrayType.isArray()) {
1429 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1430 }
1431 throw member.makeAccessException("cannot make variable arity", null);
1432 }
1433
1434 /*non-public*/
1435 MethodHandle viewAsType(MethodType newType, boolean strict) {
1436 // No actual conversions, just a new view of the same method.
1437 // Note that this operation must not produce a DirectMethodHandle,
1438 // because retyped DMHs, like any transformed MHs,
1439 // cannot be cracked into MethodHandleInfo.
1440 assert viewAsTypeChecks(newType, strict);
1441 BoundMethodHandle mh = rebind();
1442 return mh.copyWith(newType, mh.form);
1443 }
1444
1445 /*non-public*/
1446 boolean viewAsTypeChecks(MethodType newType, boolean strict) {
1447 if (strict) {
1448 assert(type().isViewableAs(newType, true))
1449 : Arrays.asList(this, newType);
1450 } else {
1451 assert(type().basicType().isViewableAs(newType.basicType(), true))
1452 : Arrays.asList(this, newType);
|
198 * This is done via a reflective, capability-based API called
199 * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
200 * For example, a static method handle can be obtained
201 * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
202 * There are also conversion methods from Core Reflection API objects,
203 * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
204 * <p>
205 * Like classes and strings, method handles that correspond to accessible
206 * fields, methods, and constructors can also be represented directly
207 * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
208 * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
209 * refers directly to an associated {@code CONSTANT_Methodref},
210 * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
211 * constant pool entry.
212 * (For full details on method handle constants,
213 * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
214 * <p>
215 * Method handles produced by lookups or constant loads from methods or
216 * constructors with the variable arity modifier bit ({@code 0x0080})
217 * have a corresponding variable arity, as if they were defined with
218 * the help of {@link #asVarargsCollector asVarargsCollector}
219 * or {@link #withVarargs withVarargs}.
220 * <p>
221 * A method reference may refer either to a static or non-static method.
222 * In the non-static case, the method handle type includes an explicit
223 * receiver argument, prepended before any other arguments.
224 * In the method handle's type, the initial receiver argument is typed
225 * according to the class under which the method was initially requested.
226 * (E.g., if a non-static method handle is obtained via {@code ldc},
227 * the type of the receiver is the class named in the constant pool entry.)
228 * <p>
229 * Method handle constants are subject to the same link-time access checks
230 * their corresponding bytecode instructions, and the {@code ldc} instruction
231 * will throw corresponding linkage errors if the bytecode behaviors would
232 * throw such errors.
233 * <p>
234 * As a corollary of this, access to protected members is restricted
235 * to receivers only of the accessing class, or one of its subclasses,
236 * and the accessing class must in turn be a subclass (or package sibling)
237 * of the protected member's defining class.
238 * If a method reference refers to a protected non-static method or field
239 * of a class outside the current package, the receiver argument will
952 MethodType needType = mtype.asSpreaderType(arrayType, pos, arrayLength);
953 if (!fail) return needType;
954 // elicit an error:
955 this.asType(needType);
956 throw newInternalError("should not return", null);
957 }
958
959 private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
960 Class<?> arrayElement = arrayType.getComponentType();
961 if (arrayElement == null)
962 throw newIllegalArgumentException("not an array type", arrayType);
963 if ((arrayLength & 0x7F) != arrayLength) {
964 if ((arrayLength & 0xFF) != arrayLength)
965 throw newIllegalArgumentException("array length is not legal", arrayLength);
966 assert(arrayLength >= 128);
967 if (arrayElement == long.class ||
968 arrayElement == double.class)
969 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
970 }
971 }
972 /**
973 * Adapts this method handle to be {@linkplain #asVarargsCollector variable arity}
974 * if the boolean flag is true, else {@linkplain #asFixedArity fixed arity}.
975 * If the method handle is already of the proper arity mode, it is returned
976 * unchanged.
977 * <p>This method is sometimes useful when adapting a method handle that
978 * may be variable arity, to ensure that the resulting adapter is also
979 * variable arity if and only if the original handle was. For example,
980 * this code changes the first argument of a handle to {@code int} without
981 * disturbing its variable arity property:
982 * {@code mh.asType(mh.type().changeParameterType(0,int.class)).withVarargs(mh.isVarargsCollector())}
983 * @param makeVarargs true if the return method handle should have variable arity behavior
984 * @return a method handle of the same type, with possibly adjusted variable arity behavior
985 * @throws IllegalArgumentException if {@code makeVarargs} is true and
986 * this method handle does not have a trailing array parameter
987 * @since 9
988 */
989 public MethodHandle withVarargs(boolean makeVarargs) {
990 if (!makeVarargs) {
991 return asFixedArity();
992 } else if (!isVarargsCollector()) {
993 return asVarargsCollector(type().lastParameterType());
994 } else {
995 return this;
996 }
997 }
998
999 /**
1000 * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
1001 * positional arguments and collects them into an array argument.
1002 * The new method handle adapts, as its <i>target</i>,
1003 * the current method handle. The type of the adapter will be
1004 * the same as the type of the target, except that a single trailing
1005 * parameter (usually of type {@code arrayType}) is replaced by
1006 * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
1007 * <p>
1008 * If the array type differs from the final argument type on the original target,
1009 * the original target is adapted to take the array type directly,
1010 * as if by a call to {@link #asType asType}.
1011 * <p>
1012 * When called, the adapter replaces its trailing {@code arrayLength}
1013 * arguments by a single new array of type {@code arrayType}, whose elements
1014 * comprise (in order) the replaced arguments.
1015 * Finally the target is called.
1016 * What the target eventually returns is returned unchanged by the adapter.
1017 * <p>
1018 * (The array may also be a shared constant when {@code arrayLength} is zero.)
1019 * <p>
1020 * (<em>Note:</em> The {@code arrayType} is often identical to the last
1021 * parameter type of the original target.
1022 * It is an explicit argument for symmetry with {@code asSpreader}, and also
1023 * to allow the target to use a simple {@code Object} as its last parameter type.)
1024 * <p>
1025 * In order to create a collecting adapter which is not restricted to a particular
1026 * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector}
1027 * or {@link #withVarargs withVarargs} instead.
1028 * <p>
1029 * Here are some examples of array-collecting method handles:
1030 * <blockquote><pre>{@code
1031 MethodHandle deepToString = publicLookup()
1032 .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
1033 assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));
1034 MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
1035 assertEquals(methodType(String.class, Object.class), ts1.type());
1036 //assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"})); //FAIL
1037 assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"}));
1038 // arrayType can be a subtype of Object[]
1039 MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
1040 assertEquals(methodType(String.class, String.class, String.class), ts2.type());
1041 assertEquals("[two, too]", (String) ts2.invokeExact("two", "too"));
1042 MethodHandle ts0 = deepToString.asCollector(Object[].class, 0);
1043 assertEquals("[]", (String) ts0.invokeExact());
1044 // collectors can be nested, Lisp-style
1045 MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2);
1046 assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D")));
1047 // arrayType can be any primitive array type
1223 * Therefore, a variable arity adapter responds
1224 * to an {@code asType} request by building a fixed arity collector,
1225 * if and only if the adapter and requested type differ either
1226 * in arity or trailing argument type.
1227 * The resulting fixed arity collector has its type further adjusted
1228 * (if necessary) to the requested type by pairwise conversion,
1229 * as if by another application of {@code asType}.
1230 * <p>
1231 * When a method handle is obtained by executing an {@code ldc} instruction
1232 * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
1233 * as a variable arity method (with the modifier bit {@code 0x0080}),
1234 * the method handle will accept multiple arities, as if the method handle
1235 * constant were created by means of a call to {@code asVarargsCollector}.
1236 * <p>
1237 * In order to create a collecting adapter which collects a predetermined
1238 * number of arguments, and whose type reflects this predetermined number,
1239 * use {@link #asCollector asCollector} instead.
1240 * <p>
1241 * No method handle transformations produce new method handles with
1242 * variable arity, unless they are documented as doing so.
1243 * Therefore, besides {@code asVarargsCollector} and {@code withVarargs},
1244 * all methods in {@code MethodHandle} and {@code MethodHandles}
1245 * will return a method handle with fixed arity,
1246 * except in the cases where they are specified to return their original
1247 * operand (e.g., {@code asType} of the method handle's own type).
1248 * <p>
1249 * Calling {@code asVarargsCollector} on a method handle which is already
1250 * of variable arity will produce a method handle with the same type and behavior.
1251 * It may (or may not) return the original variable arity method handle.
1252 * <p>
1253 * Here is an example, of a list-making variable arity method handle:
1254 * <blockquote><pre>{@code
1255 MethodHandle deepToString = publicLookup()
1256 .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
1257 MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
1258 assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));
1259 assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));
1260 assertEquals("[won]", (String) ts1.invoke( "won" ));
1261 assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
1262 // findStatic of Arrays.asList(...) produces a variable arity method handle:
1263 MethodHandle asList = publicLookup()
1280 * of the Java rules for variable arity methods.
1281 * In both cases, callers to a variable arity method or method handle
1282 * can either pass zero or more positional arguments, or else pass
1283 * pre-collected arrays of any length. Users should be aware of the
1284 * special role of the final argument, and of the effect of a
1285 * type match on that final argument, which determines whether
1286 * or not a single trailing argument is interpreted as a whole
1287 * array or a single element of an array to be collected.
1288 * Note that the dynamic type of the trailing argument has no
1289 * effect on this decision, only a comparison between the symbolic
1290 * type descriptor of the call site and the type descriptor of the method handle.)
1291 *
1292 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1293 * @return a new method handle which can collect any number of trailing arguments
1294 * into an array, before calling the original method handle
1295 * @throws NullPointerException if {@code arrayType} is a null reference
1296 * @throws IllegalArgumentException if {@code arrayType} is not an array type
1297 * or {@code arrayType} is not assignable to this method handle's trailing parameter type
1298 * @see #asCollector
1299 * @see #isVarargsCollector
1300 * @see #withVarargs
1301 * @see #asFixedArity
1302 */
1303 public MethodHandle asVarargsCollector(Class<?> arrayType) {
1304 Objects.requireNonNull(arrayType);
1305 boolean lastMatch = asCollectorChecks(arrayType, type().parameterCount() - 1, 0);
1306 if (isVarargsCollector() && lastMatch)
1307 return this;
1308 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1309 }
1310
1311 /**
1312 * Determines if this method handle
1313 * supports {@linkplain #asVarargsCollector variable arity} calls.
1314 * Such method handles arise from the following sources:
1315 * <ul>
1316 * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
1317 * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
1318 * which resolves to a variable arity Java method or constructor
1319 * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
1320 * which resolves to a variable arity Java method or constructor
1352 MethodHandle asListFix = asListVar.asFixedArity();
1353 assertEquals("[1]", asListVar.invoke(1).toString());
1354 Exception caught = null;
1355 try { asListFix.invoke((Object)1); }
1356 catch (Exception ex) { caught = ex; }
1357 assert(caught instanceof ClassCastException);
1358 assertEquals("[two, too]", asListVar.invoke("two", "too").toString());
1359 try { asListFix.invoke("two", "too"); }
1360 catch (Exception ex) { caught = ex; }
1361 assert(caught instanceof WrongMethodTypeException);
1362 Object[] argv = { "three", "thee", "tee" };
1363 assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
1364 assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString());
1365 assertEquals(1, ((List) asListVar.invoke((Object)argv)).size());
1366 assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
1367 * }</pre></blockquote>
1368 *
1369 * @return a new method handle which accepts only a fixed number of arguments
1370 * @see #asVarargsCollector
1371 * @see #isVarargsCollector
1372 * @see #withVarargs
1373 */
1374 public MethodHandle asFixedArity() {
1375 assert(!isVarargsCollector());
1376 return this;
1377 }
1378
1379 /**
1380 * Binds a value {@code x} to the first argument of a method handle, without invoking it.
1381 * The new method handle adapts, as its <i>target</i>,
1382 * the current method handle by binding it to the given argument.
1383 * The type of the bound handle will be
1384 * the same as the type of the target, except that a single leading
1385 * reference parameter will be omitted.
1386 * <p>
1387 * When called, the bound handle inserts the given value {@code x}
1388 * as a new leading argument to the target. The other arguments are
1389 * also passed unchanged.
1390 * What the target eventually returns is returned unchanged by the bound handle.
1391 * <p>
1392 * The reference {@code x} must be convertible to the first parameter
1437 /** Return a string with a several lines describing the method handle structure.
1438 * This string would be suitable for display in an IDE debugger.
1439 */
1440 String debugString() {
1441 return type+" : "+internalForm()+internalProperties();
1442 }
1443
1444 //// Implementation methods.
1445 //// Sub-classes can override these default implementations.
1446 //// All these methods assume arguments are already validated.
1447
1448 // Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
1449
1450 BoundMethodHandle bindArgumentL(int pos, Object value) {
1451 return rebind().bindArgumentL(pos, value);
1452 }
1453
1454 /*non-public*/
1455 MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1456 if (!member.isVarargs()) return this;
1457 try {
1458 return this.withVarargs(true);
1459 } catch (IllegalArgumentException ex) {
1460 throw member.makeAccessException("cannot make variable arity", null);
1461 }
1462 }
1463
1464 /*non-public*/
1465 MethodHandle viewAsType(MethodType newType, boolean strict) {
1466 // No actual conversions, just a new view of the same method.
1467 // Note that this operation must not produce a DirectMethodHandle,
1468 // because retyped DMHs, like any transformed MHs,
1469 // cannot be cracked into MethodHandleInfo.
1470 assert viewAsTypeChecks(newType, strict);
1471 BoundMethodHandle mh = rebind();
1472 return mh.copyWith(newType, mh.form);
1473 }
1474
1475 /*non-public*/
1476 boolean viewAsTypeChecks(MethodType newType, boolean strict) {
1477 if (strict) {
1478 assert(type().isViewableAs(newType, true))
1479 : Arrays.asList(this, newType);
1480 } else {
1481 assert(type().basicType().isViewableAs(newType.basicType(), true))
1482 : Arrays.asList(this, newType);
|