< prev index next >

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

Print this page




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


< prev index next >