< prev index next >

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

Print this page
rev 13106 : 8139885: implement JEP 274: enhanced method handles


 855 MethodHandle caString3 = caToString.asCollector(char[].class, 3);
 856 assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
 857 MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
 858 assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
 859      * }</pre></blockquote>
 860      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 861      * @param arrayLength the number of arguments to spread from an incoming array argument
 862      * @return a new method handle which spreads its final array argument,
 863      *         before calling the original method handle
 864      * @throws NullPointerException if {@code arrayType} is a null reference
 865      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 866      *         or if target does not have at least
 867      *         {@code arrayLength} parameter types,
 868      *         or if {@code arrayLength} is negative,
 869      *         or if the resulting method handle's type would have
 870      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 871      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 872      * @see #asCollector
 873      */
 874     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
 875         MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
 876         int arity = type().parameterCount();
 877         int spreadArgPos = arity - arrayLength;









































 878         MethodHandle afterSpread = this.asType(postSpreadType);
 879         BoundMethodHandle mh = afterSpread.rebind();
 880         LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
 881         MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
 882         return mh.copyWith(preSpreadType, lform);
 883     }
 884 
 885     /**
 886      * See if {@code asSpreader} can be validly called with the given arguments.
 887      * Return the type of the method handle call after spreading but before conversions.
 888      */
 889     private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
 890         spreadArrayChecks(arrayType, arrayLength);
 891         int nargs = type().parameterCount();
 892         if (nargs < arrayLength || arrayLength < 0)
 893             throw newIllegalArgumentException("bad spread array length");



 894         Class<?> arrayElement = arrayType.getComponentType();
 895         MethodType mtype = type();
 896         boolean match = true, fail = false;
 897         for (int i = nargs - arrayLength; i < nargs; i++) {
 898             Class<?> ptype = mtype.parameterType(i);
 899             if (ptype != arrayElement) {
 900                 match = false;
 901                 if (!MethodType.canConvert(arrayElement, ptype)) {
 902                     fail = true;
 903                     break;
 904                 }
 905             }
 906         }
 907         if (match)  return mtype;
 908         MethodType needType = mtype.asSpreaderType(arrayType, arrayLength);
 909         if (!fail)  return needType;
 910         // elicit an error:
 911         this.asType(needType);
 912         throw newInternalError("should not return", null);
 913     }
 914 
 915     private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
 916         Class<?> arrayElement = arrayType.getComponentType();
 917         if (arrayElement == null)
 918             throw newIllegalArgumentException("not an array type", arrayType);
 919         if ((arrayLength & 0x7F) != arrayLength) {
 920             if ((arrayLength & 0xFF) != arrayLength)
 921                 throw newIllegalArgumentException("array length is not legal", arrayLength);
 922             assert(arrayLength >= 128);
 923             if (arrayElement == long.class ||
 924                 arrayElement == double.class)
 925                 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
 926         }
 927     }
 928 


 981 MethodHandle longsToString = publicLookup()
 982   .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
 983   .asCollector(long[].class, 1);
 984 assertEquals("[123]", (String) longsToString.invokeExact((long)123));
 985      * }</pre></blockquote>
 986      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
 987      * @param arrayLength the number of arguments to collect into a new array argument
 988      * @return a new method handle which collects some trailing argument
 989      *         into an array, before calling the original method handle
 990      * @throws NullPointerException if {@code arrayType} is a null reference
 991      * @throws IllegalArgumentException if {@code arrayType} is not an array type
 992      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
 993      *         or {@code arrayLength} is not a legal array size,
 994      *         or the resulting method handle's type would have
 995      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 996      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 997      * @see #asSpreader
 998      * @see #asVarargsCollector
 999      */
1000     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
1001         asCollectorChecks(arrayType, arrayLength);
1002         int collectArgPos = type().parameterCount() - 1;











































1003         BoundMethodHandle mh = rebind();
1004         MethodType resultType = type().asCollectorType(arrayType, arrayLength);
1005         MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1006         LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
1007         if (lform != null) {
1008             return mh.copyWith(resultType, lform);
1009         }
1010         lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
1011         return mh.copyWithExtendL(resultType, lform, newArray);
1012     }
1013 
1014     /**
1015      * See if {@code asCollector} can be validly called with the given arguments.
1016      * Return false if the last parameter is not an exact match to arrayType.
1017      */
1018     /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
1019         spreadArrayChecks(arrayType, arrayLength);
1020         int nargs = type().parameterCount();



1021         if (nargs != 0) {
1022             Class<?> lastParam = type().parameterType(nargs-1);
1023             if (lastParam == arrayType)  return true;
1024             if (lastParam.isAssignableFrom(arrayType))  return false;
1025         }
1026         throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
1027     }
1028 
1029     /**
1030      * Makes a <em>variable arity</em> adapter which is able to accept
1031      * any number of trailing positional arguments and collect them
1032      * into an array argument.
1033      * <p>
1034      * The type and behavior of the adapter will be the same as
1035      * the type and behavior of the target, except that certain
1036      * {@code invoke} and {@code asType} requests can lead to
1037      * trailing positional arguments being collected into target's
1038      * trailing parameter.
1039      * Also, the last parameter type of the adapter will be
1040      * {@code arrayType}, even if the target has a different
1041      * last parameter type.
1042      * <p>
1043      * This transformation may return {@code this} if the method handle is
1044      * already of variable arity and its trailing parameter type
1045      * is identical to {@code arrayType}.
1046      * <p>


1161      * special role of the final argument, and of the effect of a
1162      * type match on that final argument, which determines whether
1163      * or not a single trailing argument is interpreted as a whole
1164      * array or a single element of an array to be collected.
1165      * Note that the dynamic type of the trailing argument has no
1166      * effect on this decision, only a comparison between the symbolic
1167      * type descriptor of the call site and the type descriptor of the method handle.)
1168      *
1169      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1170      * @return a new method handle which can collect any number of trailing arguments
1171      *         into an array, before calling the original method handle
1172      * @throws NullPointerException if {@code arrayType} is a null reference
1173      * @throws IllegalArgumentException if {@code arrayType} is not an array type
1174      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type
1175      * @see #asCollector
1176      * @see #isVarargsCollector
1177      * @see #asFixedArity
1178      */
1179     public MethodHandle asVarargsCollector(Class<?> arrayType) {
1180         Objects.requireNonNull(arrayType);
1181         boolean lastMatch = asCollectorChecks(arrayType, 0);
1182         if (isVarargsCollector() && lastMatch)
1183             return this;
1184         return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1185     }
1186 
1187     /**
1188      * Determines if this method handle
1189      * supports {@linkplain #asVarargsCollector variable arity} calls.
1190      * Such method handles arise from the following sources:
1191      * <ul>
1192      * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
1193      * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
1194      *     which resolves to a variable arity Java method or constructor
1195      * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
1196      *     which resolves to a variable arity Java method or constructor
1197      * </ul>
1198      * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
1199      * @see #asVarargsCollector
1200      * @see #asFixedArity
1201      */


1324     }
1325 
1326     /*non-public*/
1327     MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1328         if (!member.isVarargs())  return this;
1329         Class<?> arrayType = type().lastParameterType();
1330         if (arrayType.isArray()) {
1331             return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1332         }
1333         throw member.makeAccessException("cannot make variable arity", null);
1334     }
1335 
1336     /*non-public*/
1337     MethodHandle viewAsType(MethodType newType, boolean strict) {
1338         // No actual conversions, just a new view of the same method.
1339         // Note that this operation must not produce a DirectMethodHandle,
1340         // because retyped DMHs, like any transformed MHs,
1341         // cannot be cracked into MethodHandleInfo.
1342         assert viewAsTypeChecks(newType, strict);
1343         BoundMethodHandle mh = rebind();
1344         assert(!((MethodHandle)mh instanceof DirectMethodHandle));
1345         return mh.copyWith(newType, mh.form);
1346     }
1347 
1348     /*non-public*/
1349     boolean viewAsTypeChecks(MethodType newType, boolean strict) {
1350         if (strict) {
1351             assert(type().isViewableAs(newType, true))
1352                 : Arrays.asList(this, newType);
1353         } else {
1354             assert(type().basicType().isViewableAs(newType.basicType(), true))
1355                 : Arrays.asList(this, newType);
1356         }
1357         return true;
1358     }
1359 
1360     // Decoding
1361 
1362     /*non-public*/
1363     LambdaForm internalForm() {
1364         return form;




 855 MethodHandle caString3 = caToString.asCollector(char[].class, 3);
 856 assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
 857 MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
 858 assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
 859      * }</pre></blockquote>
 860      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 861      * @param arrayLength the number of arguments to spread from an incoming array argument
 862      * @return a new method handle which spreads its final array argument,
 863      *         before calling the original method handle
 864      * @throws NullPointerException if {@code arrayType} is a null reference
 865      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 866      *         or if target does not have at least
 867      *         {@code arrayLength} parameter types,
 868      *         or if {@code arrayLength} is negative,
 869      *         or if the resulting method handle's type would have
 870      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 871      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 872      * @see #asCollector
 873      */
 874     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
 875         return asSpreader(type().parameterCount() - arrayLength, arrayType, arrayLength);
 876     }
 877 
 878     /**
 879      * Makes an <em>array-spreading</em> method handle, which accepts an array argument at a given position and spreads
 880      * its elements as positional arguments in place of the array. The new method handle adapts, as its <i>target</i>,
 881      * the current method handle. The type of the adapter will be the same as the type of the target, except that the
 882      * {@code arrayLength} parameters of the target's type, starting at the zero-based position {@code spreadArgPos},
 883      * are replaced by a single array parameter of type {@code arrayType}.
 884      * <p>
 885      * This method behaves very much like {@link #asSpreader(Class, int)}, but accepts an additional {@code spreadArgPos}
 886      * argument to indicate at which position in the parameter list the spreading should take place.
 887      * <p>
 888      * @apiNote Example:
 889      * <blockquote><pre>{@code
 890     MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
 891     MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2);
 892     Object[] ints = new Object[]{3, 9, 7, 7};
 893     Comparator<Integer> cmp = (a, b) -> a - b;
 894     assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0);
 895     assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0);
 896     assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0);
 897      * }</pre></blockquote>
 898      * @param spreadArgPos the position (zero-based index) in the argument list at which spreading should start.
 899      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 900      * @param arrayLength the number of arguments to spread from an incoming array argument
 901      * @return a new method handle which spreads an array argument at a given position,
 902      *         before calling the original method handle
 903      * @throws NullPointerException if {@code arrayType} is a null reference
 904      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 905      *         or if target does not have at least
 906      *         {@code arrayLength} parameter types,
 907      *         or if {@code arrayLength} is negative,
 908      *         or if {@code spreadArgPos} has an illegal value (negative, or together with arrayLength exceeding the
 909      *         number of arguments),
 910      *         or if the resulting method handle's type would have
 911      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 912      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 913      *
 914      * @see #asSpreader(Class, int)
 915      * @since 9
 916      */
 917     public MethodHandle asSpreader(int spreadArgPos, Class<?> arrayType, int arrayLength) {
 918         MethodType postSpreadType = asSpreaderChecks(arrayType, spreadArgPos, arrayLength);
 919         MethodHandle afterSpread = this.asType(postSpreadType);
 920         BoundMethodHandle mh = afterSpread.rebind();
 921         LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
 922         MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, spreadArgPos + arrayLength, arrayType);
 923         return mh.copyWith(preSpreadType, lform);
 924     }
 925 
 926     /**
 927      * See if {@code asSpreader} can be validly called with the given arguments.
 928      * Return the type of the method handle call after spreading but before conversions.
 929      */
 930     private MethodType asSpreaderChecks(Class<?> arrayType, int pos, int arrayLength) {
 931         spreadArrayChecks(arrayType, arrayLength);
 932         int nargs = type().parameterCount();
 933         if (nargs < arrayLength || arrayLength < 0)
 934             throw newIllegalArgumentException("bad spread array length");
 935         if (pos < 0 || pos + arrayLength > nargs) {
 936             throw newIllegalArgumentException("bad spread position");
 937         }
 938         Class<?> arrayElement = arrayType.getComponentType();
 939         MethodType mtype = type();
 940         boolean match = true, fail = false;
 941         for (int i = pos; i < arrayLength; i++) {
 942             Class<?> ptype = mtype.parameterType(i);
 943             if (ptype != arrayElement) {
 944                 match = false;
 945                 if (!MethodType.canConvert(arrayElement, ptype)) {
 946                     fail = true;
 947                     break;
 948                 }
 949             }
 950         }
 951         if (match)  return mtype;
 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 


1025 MethodHandle longsToString = publicLookup()
1026   .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
1027   .asCollector(long[].class, 1);
1028 assertEquals("[123]", (String) longsToString.invokeExact((long)123));
1029      * }</pre></blockquote>
1030      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1031      * @param arrayLength the number of arguments to collect into a new array argument
1032      * @return a new method handle which collects some trailing argument
1033      *         into an array, before calling the original method handle
1034      * @throws NullPointerException if {@code arrayType} is a null reference
1035      * @throws IllegalArgumentException if {@code arrayType} is not an array type
1036      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
1037      *         or {@code arrayLength} is not a legal array size,
1038      *         or the resulting method handle's type would have
1039      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
1040      * @throws WrongMethodTypeException if the implied {@code asType} call fails
1041      * @see #asSpreader
1042      * @see #asVarargsCollector
1043      */
1044     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
1045         return asCollector(type().parameterCount() - 1, arrayType, arrayLength);
1046     }
1047 
1048     /**
1049      * Makes an <em>array-collecting</em> method handle, which accepts a given number of positional arguments starting
1050      * at a given position, and collects them into an array argument. The new method handle adapts, as its
1051      * <i>target</i>, the current method handle. The type of the adapter will be the same as the type of the target,
1052      * except that the parameter at the position indicated by {@code collectArgPos} (usually of type {@code arrayType})
1053      * is replaced by {@code arrayLength} parameters whose type is element type of {@code arrayType}.
1054      * <p>
1055      * This method behaves very much like {@link #asCollector(Class, int)}, but differs in that its {@code
1056      * collectArgPos} argument indicates at which position in the parameter list arguments should be collected. This
1057      * index is zero-based.
1058      * <p>
1059      * @apiNote Examples:
1060      * <blockquote><pre>{@code
1061     StringWriter swr = new StringWriter();
1062     MethodHandle swWrite = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, char[].class, int.class, int.class)).bindTo(swr);
1063     MethodHandle swWrite4 = swWrite.asCollector(0, char[].class, 4);
1064     swWrite4.invoke('A', 'B', 'C', 'D', 1, 2);
1065     assertEquals("BC", swr.toString());
1066     swWrite4.invoke('P', 'Q', 'R', 'S', 0, 4);
1067     assertEquals("BCPQRS", swr.toString());
1068     swWrite4.invoke('W', 'X', 'Y', 'Z', 3, 1);
1069     assertEquals("BCPQRSZ", swr.toString());
1070      * }</pre></blockquote>
1071      * @param collectArgPos the zero-based position in the parameter list at which to start collecting.
1072      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1073      * @param arrayLength the number of arguments to collect into a new array argument
1074      * @return a new method handle which collects some arguments
1075      *         into an array, before calling the original method handle
1076      * @throws NullPointerException if {@code arrayType} is a null reference
1077      * @throws IllegalArgumentException if {@code arrayType} is not an array type
1078      *         or {@code arrayType} is not assignable to this method handle's array parameter type,
1079      *         or {@code arrayLength} is not a legal array size,
1080      *         or {@code collectArgPos} has an illegal value (negative, or greater than the number of arguments),
1081      *         or the resulting method handle's type would have
1082      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
1083      * @throws WrongMethodTypeException if the implied {@code asType} call fails
1084      *
1085      * @see #asCollector(Class, int)
1086      * @since 9
1087      */
1088     public MethodHandle asCollector(int collectArgPos, Class<?> arrayType, int arrayLength) {
1089         asCollectorChecks(arrayType, collectArgPos, arrayLength);
1090         BoundMethodHandle mh = rebind();
1091         MethodType resultType = type().asCollectorType(arrayType, collectArgPos, arrayLength);
1092         MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1093         LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
1094         if (lform != null) {
1095             return mh.copyWith(resultType, lform);
1096         }
1097         lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
1098         return mh.copyWithExtendL(resultType, lform, newArray);
1099     }
1100 
1101     /**
1102      * See if {@code asCollector} can be validly called with the given arguments.
1103      * Return false if the last parameter is not an exact match to arrayType.
1104      */
1105     /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int pos, int arrayLength) {
1106         spreadArrayChecks(arrayType, arrayLength);
1107         int nargs = type().parameterCount();
1108         if (pos < 0 || pos >= nargs) {
1109             throw newIllegalArgumentException("bad collect position");
1110         }
1111         if (nargs != 0) {
1112             Class<?> param = type().parameterType(pos);
1113             if (param == arrayType)  return true;
1114             if (param.isAssignableFrom(arrayType))  return false;
1115         }
1116         throw newIllegalArgumentException("array type not assignable to argument", this, arrayType);
1117     }
1118 
1119     /**
1120      * Makes a <em>variable arity</em> adapter which is able to accept
1121      * any number of trailing positional arguments and collect them
1122      * into an array argument.
1123      * <p>
1124      * The type and behavior of the adapter will be the same as
1125      * the type and behavior of the target, except that certain
1126      * {@code invoke} and {@code asType} requests can lead to
1127      * trailing positional arguments being collected into target's
1128      * trailing parameter.
1129      * Also, the last parameter type of the adapter will be
1130      * {@code arrayType}, even if the target has a different
1131      * last parameter type.
1132      * <p>
1133      * This transformation may return {@code this} if the method handle is
1134      * already of variable arity and its trailing parameter type
1135      * is identical to {@code arrayType}.
1136      * <p>


1251      * special role of the final argument, and of the effect of a
1252      * type match on that final argument, which determines whether
1253      * or not a single trailing argument is interpreted as a whole
1254      * array or a single element of an array to be collected.
1255      * Note that the dynamic type of the trailing argument has no
1256      * effect on this decision, only a comparison between the symbolic
1257      * type descriptor of the call site and the type descriptor of the method handle.)
1258      *
1259      * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
1260      * @return a new method handle which can collect any number of trailing arguments
1261      *         into an array, before calling the original method handle
1262      * @throws NullPointerException if {@code arrayType} is a null reference
1263      * @throws IllegalArgumentException if {@code arrayType} is not an array type
1264      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type
1265      * @see #asCollector
1266      * @see #isVarargsCollector
1267      * @see #asFixedArity
1268      */
1269     public MethodHandle asVarargsCollector(Class<?> arrayType) {
1270         Objects.requireNonNull(arrayType);
1271         boolean lastMatch = asCollectorChecks(arrayType, type().parameterCount() - 1, 0);
1272         if (isVarargsCollector() && lastMatch)
1273             return this;
1274         return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1275     }
1276 
1277     /**
1278      * Determines if this method handle
1279      * supports {@linkplain #asVarargsCollector variable arity} calls.
1280      * Such method handles arise from the following sources:
1281      * <ul>
1282      * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
1283      * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
1284      *     which resolves to a variable arity Java method or constructor
1285      * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
1286      *     which resolves to a variable arity Java method or constructor
1287      * </ul>
1288      * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
1289      * @see #asVarargsCollector
1290      * @see #asFixedArity
1291      */


1414     }
1415 
1416     /*non-public*/
1417     MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
1418         if (!member.isVarargs())  return this;
1419         Class<?> arrayType = type().lastParameterType();
1420         if (arrayType.isArray()) {
1421             return MethodHandleImpl.makeVarargsCollector(this, arrayType);
1422         }
1423         throw member.makeAccessException("cannot make variable arity", null);
1424     }
1425 
1426     /*non-public*/
1427     MethodHandle viewAsType(MethodType newType, boolean strict) {
1428         // No actual conversions, just a new view of the same method.
1429         // Note that this operation must not produce a DirectMethodHandle,
1430         // because retyped DMHs, like any transformed MHs,
1431         // cannot be cracked into MethodHandleInfo.
1432         assert viewAsTypeChecks(newType, strict);
1433         BoundMethodHandle mh = rebind();

1434         return mh.copyWith(newType, mh.form);
1435     }
1436 
1437     /*non-public*/
1438     boolean viewAsTypeChecks(MethodType newType, boolean strict) {
1439         if (strict) {
1440             assert(type().isViewableAs(newType, true))
1441                 : Arrays.asList(this, newType);
1442         } else {
1443             assert(type().basicType().isViewableAs(newType.basicType(), true))
1444                 : Arrays.asList(this, newType);
1445         }
1446         return true;
1447     }
1448 
1449     // Decoding
1450 
1451     /*non-public*/
1452     LambdaForm internalForm() {
1453         return form;


< prev index next >