749 * @see MethodHandles#explicitCastArguments
750 */
751 public MethodHandle asType(MethodType newType) {
752 // Fast path alternative to a heavyweight {@code asType} call.
753 // Return 'this' if the conversion will be a no-op.
754 if (newType == type) {
755 return this;
756 }
757 // Return 'this.asTypeCache' if the conversion is already memoized.
758 MethodHandle atc = asTypeCache;
759 if (atc != null && newType == atc.type) {
760 return atc;
761 }
762 return asTypeUncached(newType);
763 }
764
765 /** Override this to change asType behavior. */
766 /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
767 if (!type.isConvertibleTo(newType))
768 throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
769 return asTypeCache = convertArguments(newType);
770 }
771
772 /**
773 * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
774 * and spreads its elements as positional arguments.
775 * The new method handle adapts, as its <i>target</i>,
776 * the current method handle. The type of the adapter will be
777 * the same as the type of the target, except that the final
778 * {@code arrayLength} parameters of the target's type are replaced
779 * by a single array parameter of type {@code arrayType}.
780 * <p>
781 * If the array element type differs from any of the corresponding
782 * argument types on the original target,
783 * the original target is adapted to take the array elements directly,
784 * as if by a call to {@link #asType asType}.
785 * <p>
786 * When called, the adapter replaces a trailing array argument
787 * by the array's elements, each as its own argument to the target.
788 * (The order of the arguments is preserved.)
789 * They are converted pairwise by casting and/or unboxing
962 * }</pre></blockquote>
963 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
964 * @param arrayLength the number of arguments to collect into a new array argument
965 * @return a new method handle which collects some trailing argument
966 * into an array, before calling the original method handle
967 * @throws NullPointerException if {@code arrayType} is a null reference
968 * @throws IllegalArgumentException if {@code arrayType} is not an array type
969 * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
970 * or {@code arrayLength} is not a legal array size,
971 * or the resulting method handle's type would have
972 * <a href="MethodHandle.html#maxarity">too many parameters</a>
973 * @throws WrongMethodTypeException if the implied {@code asType} call fails
974 * @see #asSpreader
975 * @see #asVarargsCollector
976 */
977 public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
978 asCollectorChecks(arrayType, arrayLength);
979 int collectArgPos = type().parameterCount()-1;
980 MethodHandle target = this;
981 if (arrayType != type().parameterType(collectArgPos))
982 target = convertArguments(type().changeParameterType(collectArgPos, arrayType));
983 MethodHandle collector = MethodHandleImpl.varargsArray(arrayType, arrayLength);
984 return MethodHandles.collectArguments(target, collectArgPos, collector);
985 }
986
987 /**
988 * See if {@code asCollector} can be validly called with the given arguments.
989 * Return false if the last parameter is not an exact match to arrayType.
990 */
991 /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
992 spreadArrayChecks(arrayType, arrayLength);
993 int nargs = type().parameterCount();
994 if (nargs != 0) {
995 Class<?> lastParam = type().parameterType(nargs-1);
996 if (lastParam == arrayType) return true;
997 if (lastParam.isAssignableFrom(arrayType)) return false;
998 }
999 throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
1000 }
1001
1002 /**
1235 * When called, the bound handle inserts the given value {@code x}
1236 * as a new leading argument to the target. The other arguments are
1237 * also passed unchanged.
1238 * What the target eventually returns is returned unchanged by the bound handle.
1239 * <p>
1240 * The reference {@code x} must be convertible to the first parameter
1241 * type of the target.
1242 * <p>
1243 * (<em>Note:</em> Because method handles are immutable, the target method handle
1244 * retains its original type and behavior.)
1245 * @param x the value to bind to the first argument of the target
1246 * @return a new method handle which prepends the given value to the incoming
1247 * argument list, before calling the original method handle
1248 * @throws IllegalArgumentException if the target does not have a
1249 * leading parameter type that is a reference type
1250 * @throws ClassCastException if {@code x} cannot be converted
1251 * to the leading parameter type of the target
1252 * @see MethodHandles#insertArguments
1253 */
1254 public MethodHandle bindTo(Object x) {
1255 Class<?> ptype;
1256 @SuppressWarnings("LocalVariableHidesMemberVariable")
1257 MethodType type = type();
1258 if (type.parameterCount() == 0 ||
1259 (ptype = type.parameterType(0)).isPrimitive())
1260 throw newIllegalArgumentException("no leading reference parameter", x);
1261 x = ptype.cast(x); // throw CCE if needed
1262 return bindReceiver(x);
1263 }
1264
1265 /**
1266 * Returns a string representation of the method handle,
1267 * starting with the string {@code "MethodHandle"} and
1268 * ending with the string representation of the method handle's type.
1269 * In other words, this method returns a string equal to the value of:
1270 * <blockquote><pre>{@code
1271 * "MethodHandle" + type().toString()
1272 * }</pre></blockquote>
1273 * <p>
1274 * (<em>Note:</em> Future releases of this API may add further information
1275 * to the string representation.
1276 * Therefore, the present syntax should not be parsed by applications.)
1277 *
1278 * @return a string representation of the method handle
1279 */
1280 @Override
1281 public String toString() {
1282 if (DEBUG_METHOD_HANDLE_NAMES) return "MethodHandle"+debugString();
1283 return standardString();
1284 }
1285 String standardString() {
1286 return "MethodHandle"+type;
1287 }
1288 /** Return a string with a several lines describing the method handle structure.
1289 * This string would be suitable for display in an IDE debugger.
1290 */
1291 String debugString() {
1292 return type+" : "+internalForm()+internalProperties();
1293 }
1294
1295 //// Implementation methods.
1296 //// Sub-classes can override these default implementations.
1297 //// All these methods assume arguments are already validated.
1298
1299 // Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
1300
1301 /*non-public*/
1302 MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1303 if (!member.isVarargs()) return this;
1304 Class<?> arrayType = type().lastParameterType();
1305 if (arrayType.isArray()) {
1306 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1307 }
1308 throw member.makeAccessException("cannot make variable arity", null);
1309 }
1310
1311 /*non-public*/
1312 MethodHandle viewAsType(MethodType newType) {
1313 // No actual conversions, just a new view of the same method.
1314 return MethodHandleImpl.makePairwiseConvert(this, newType, 0);
1315 }
1316
1317 // Decoding
1318
1319 /*non-public*/
1320 LambdaForm internalForm() {
1349 /*non-public*/
1350 boolean isInvokeSpecial() {
1351 return false; // DMH.Special returns true
1352 }
1353
1354 /*non-public*/
1355 Object internalValues() {
1356 return null;
1357 }
1358
1359 /*non-public*/
1360 Object internalProperties() {
1361 // Override to something to follow this.form, like "\n& FOO=bar"
1362 return "";
1363 }
1364
1365 //// Method handle implementation methods.
1366 //// Sub-classes can override these default implementations.
1367 //// All these methods assume arguments are already validated.
1368
1369 /*non-public*/ MethodHandle convertArguments(MethodType newType) {
1370 // Override this if it can be improved.
1371 return MethodHandleImpl.makePairwiseConvert(this, newType, 1);
1372 }
1373
1374 /*non-public*/
1375 MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
1376 // Override this if it can be improved.
1377 return rebind().bindArgument(pos, basicType, value);
1378 }
1379
1380 /*non-public*/
1381 MethodHandle bindReceiver(Object receiver) {
1382 // Override this if it can be improved.
1383 return bindArgument(0, L_TYPE, receiver);
1384 }
1385
1386 /*non-public*/
1387 MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
1388 // Override this if it can be improved.
1389 return rebind().dropArguments(srcType, pos, drops);
1390 }
1391
1392 /*non-public*/
1393 MethodHandle permuteArguments(MethodType newType, int[] reorder) {
1394 // Override this if it can be improved.
1395 return rebind().permuteArguments(newType, reorder);
1396 }
1397
1398 /*non-public*/
1399 MethodHandle rebind() {
1400 // Bind 'this' into a new invoker, of the known class BMH.
1401 MethodType type2 = type();
1402 LambdaForm form2 = reinvokerForm(this);
1403 // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
1404 return BoundMethodHandle.bindSingle(type2, form2, this);
1405 }
1406
1407 /*non-public*/
1408 MethodHandle reinvokerTarget() {
1409 throw new InternalError("not a reinvoker MH: "+this.getClass().getName()+": "+this);
1410 }
1411
1412 /** Create a LF which simply reinvokes a target of the given basic type.
1413 * The target MH must override {@link #reinvokerTarget} to provide the target.
1414 */
1415 static LambdaForm reinvokerForm(MethodHandle target) {
1416 MethodType mtype = target.type().basicType();
1417 LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE);
1418 if (reinvoker != null) return reinvoker;
1419 if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY)
|
749 * @see MethodHandles#explicitCastArguments
750 */
751 public MethodHandle asType(MethodType newType) {
752 // Fast path alternative to a heavyweight {@code asType} call.
753 // Return 'this' if the conversion will be a no-op.
754 if (newType == type) {
755 return this;
756 }
757 // Return 'this.asTypeCache' if the conversion is already memoized.
758 MethodHandle atc = asTypeCache;
759 if (atc != null && newType == atc.type) {
760 return atc;
761 }
762 return asTypeUncached(newType);
763 }
764
765 /** Override this to change asType behavior. */
766 /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
767 if (!type.isConvertibleTo(newType))
768 throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
769 return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, 1);
770 }
771
772 /**
773 * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
774 * and spreads its elements as positional arguments.
775 * The new method handle adapts, as its <i>target</i>,
776 * the current method handle. The type of the adapter will be
777 * the same as the type of the target, except that the final
778 * {@code arrayLength} parameters of the target's type are replaced
779 * by a single array parameter of type {@code arrayType}.
780 * <p>
781 * If the array element type differs from any of the corresponding
782 * argument types on the original target,
783 * the original target is adapted to take the array elements directly,
784 * as if by a call to {@link #asType asType}.
785 * <p>
786 * When called, the adapter replaces a trailing array argument
787 * by the array's elements, each as its own argument to the target.
788 * (The order of the arguments is preserved.)
789 * They are converted pairwise by casting and/or unboxing
962 * }</pre></blockquote>
963 * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
964 * @param arrayLength the number of arguments to collect into a new array argument
965 * @return a new method handle which collects some trailing argument
966 * into an array, before calling the original method handle
967 * @throws NullPointerException if {@code arrayType} is a null reference
968 * @throws IllegalArgumentException if {@code arrayType} is not an array type
969 * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
970 * or {@code arrayLength} is not a legal array size,
971 * or the resulting method handle's type would have
972 * <a href="MethodHandle.html#maxarity">too many parameters</a>
973 * @throws WrongMethodTypeException if the implied {@code asType} call fails
974 * @see #asSpreader
975 * @see #asVarargsCollector
976 */
977 public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
978 asCollectorChecks(arrayType, arrayLength);
979 int collectArgPos = type().parameterCount()-1;
980 MethodHandle target = this;
981 if (arrayType != type().parameterType(collectArgPos))
982 target = MethodHandleImpl.makePairwiseConvert(this, type().changeParameterType(collectArgPos, arrayType), 1);
983 MethodHandle collector = MethodHandleImpl.varargsArray(arrayType, arrayLength);
984 return MethodHandles.collectArguments(target, collectArgPos, collector);
985 }
986
987 /**
988 * See if {@code asCollector} can be validly called with the given arguments.
989 * Return false if the last parameter is not an exact match to arrayType.
990 */
991 /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
992 spreadArrayChecks(arrayType, arrayLength);
993 int nargs = type().parameterCount();
994 if (nargs != 0) {
995 Class<?> lastParam = type().parameterType(nargs-1);
996 if (lastParam == arrayType) return true;
997 if (lastParam.isAssignableFrom(arrayType)) return false;
998 }
999 throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
1000 }
1001
1002 /**
1235 * When called, the bound handle inserts the given value {@code x}
1236 * as a new leading argument to the target. The other arguments are
1237 * also passed unchanged.
1238 * What the target eventually returns is returned unchanged by the bound handle.
1239 * <p>
1240 * The reference {@code x} must be convertible to the first parameter
1241 * type of the target.
1242 * <p>
1243 * (<em>Note:</em> Because method handles are immutable, the target method handle
1244 * retains its original type and behavior.)
1245 * @param x the value to bind to the first argument of the target
1246 * @return a new method handle which prepends the given value to the incoming
1247 * argument list, before calling the original method handle
1248 * @throws IllegalArgumentException if the target does not have a
1249 * leading parameter type that is a reference type
1250 * @throws ClassCastException if {@code x} cannot be converted
1251 * to the leading parameter type of the target
1252 * @see MethodHandles#insertArguments
1253 */
1254 public MethodHandle bindTo(Object x) {
1255 x = type.leadingReferenceParameter().cast(x); // throw CCE if needed
1256 return bindArgumentL(0, x);
1257 }
1258
1259 /**
1260 * Returns a string representation of the method handle,
1261 * starting with the string {@code "MethodHandle"} and
1262 * ending with the string representation of the method handle's type.
1263 * In other words, this method returns a string equal to the value of:
1264 * <blockquote><pre>{@code
1265 * "MethodHandle" + type().toString()
1266 * }</pre></blockquote>
1267 * <p>
1268 * (<em>Note:</em> Future releases of this API may add further information
1269 * to the string representation.
1270 * Therefore, the present syntax should not be parsed by applications.)
1271 *
1272 * @return a string representation of the method handle
1273 */
1274 @Override
1275 public String toString() {
1276 if (DEBUG_METHOD_HANDLE_NAMES) return "MethodHandle"+debugString();
1277 return standardString();
1278 }
1279 String standardString() {
1280 return "MethodHandle"+type;
1281 }
1282 /** Return a string with a several lines describing the method handle structure.
1283 * This string would be suitable for display in an IDE debugger.
1284 */
1285 String debugString() {
1286 return type+" : "+internalForm()+internalProperties();
1287 }
1288
1289 //// Implementation methods.
1290 //// Sub-classes can override these default implementations.
1291 //// All these methods assume arguments are already validated.
1292
1293 // Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
1294
1295 BoundMethodHandle bindArgumentL(int pos, Object value) {
1296 return rebind().bindArgumentL(pos, value);
1297 }
1298
1299 /*non-public*/
1300 MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1301 if (!member.isVarargs()) return this;
1302 Class<?> arrayType = type().lastParameterType();
1303 if (arrayType.isArray()) {
1304 return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1305 }
1306 throw member.makeAccessException("cannot make variable arity", null);
1307 }
1308
1309 /*non-public*/
1310 MethodHandle viewAsType(MethodType newType) {
1311 // No actual conversions, just a new view of the same method.
1312 return MethodHandleImpl.makePairwiseConvert(this, newType, 0);
1313 }
1314
1315 // Decoding
1316
1317 /*non-public*/
1318 LambdaForm internalForm() {
1347 /*non-public*/
1348 boolean isInvokeSpecial() {
1349 return false; // DMH.Special returns true
1350 }
1351
1352 /*non-public*/
1353 Object internalValues() {
1354 return null;
1355 }
1356
1357 /*non-public*/
1358 Object internalProperties() {
1359 // Override to something to follow this.form, like "\n& FOO=bar"
1360 return "";
1361 }
1362
1363 //// Method handle implementation methods.
1364 //// Sub-classes can override these default implementations.
1365 //// All these methods assume arguments are already validated.
1366
1367 /*non-public*/
1368 BoundMethodHandle rebind() {
1369 // Bind 'this' into a new invoker, of the known class BMH.
1370 MethodType type2 = type();
1371 LambdaForm form2 = reinvokerForm(this);
1372 // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
1373 return BoundMethodHandle.bindSingle(type2, form2, this);
1374 }
1375
1376 /*non-public*/
1377 MethodHandle reinvokerTarget() {
1378 throw new InternalError("not a reinvoker MH: "+this.getClass().getName()+": "+this);
1379 }
1380
1381 /** Create a LF which simply reinvokes a target of the given basic type.
1382 * The target MH must override {@link #reinvokerTarget} to provide the target.
1383 */
1384 static LambdaForm reinvokerForm(MethodHandle target) {
1385 MethodType mtype = target.type().basicType();
1386 LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE);
1387 if (reinvoker != null) return reinvoker;
1388 if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY)
|