< prev index next >

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

Print this page

7961     private static MethodType tableSwitchChecks(MethodHandle defaultCase, MethodHandle[] caseActions) {
7962         if (caseActions.length == 0)
7963             throw new IllegalArgumentException("Not enough cases: " + Arrays.toString(caseActions));
7964 
7965         MethodType expectedType = defaultCase.type();
7966 
7967         if (!(expectedType.parameterCount() >= 1) || expectedType.parameterType(0) != int.class)
7968             throw new IllegalArgumentException(
7969                 "Case actions must have int as leading parameter: " + Arrays.toString(caseActions));
7970 
7971         for (MethodHandle mh : caseActions) {
7972             Objects.requireNonNull(mh);
7973             if (mh.type() != expectedType)
7974                 throw new IllegalArgumentException(
7975                     "Case actions must have the same type: " + Arrays.toString(caseActions));
7976         }
7977 
7978         return expectedType;
7979     }
7980 
7981     /**
7982      * Creates a var handle object, which can be used to dereference a {@linkplain java.lang.foreign.MemorySegment memory segment}
7983      * at a given byte offset, using the provided value layout.
7984      *
7985      * <p>The provided layout specifies the {@linkplain ValueLayout#carrier() carrier type},
7986      * the {@linkplain ValueLayout#byteSize() byte size},
7987      * the {@linkplain ValueLayout#byteAlignment() byte alignment} and the {@linkplain ValueLayout#order() byte order}
7988      * associated with the returned var handle.
7989      *
7990      * <p>The list of coordinate types associated with the returned var handle is {@code (MemorySegment, long)},
7991      * where the {@code long} coordinate type corresponds to byte offset into the given memory segment coordinate.
7992      * Thus, the returned var handle accesses bytes at an offset in a given memory segment, composing bytes to or from
7993      * a value of the var handle type. Moreover, the access operation will honor the endianness and the
7994      * alignment constraints expressed in the provided layout.
7995      *
7996      * <p>As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows:
7997      * {@snippet lang="java" :
7998      *     GroupLayout seq = java.lang.foreign.MemoryLayout.structLayout(
7999      *             MemoryLayout.paddingLayout(4),
8000      *             ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
8001      *     );
8002      * }
8003      * To access the member layout named {@code value}, we can construct a memory segment view var handle as follows:
8004      * {@snippet lang="java" :
8005      *     VarHandle handle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
8006      *     handle = MethodHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
8007      * }
8008      *
8009      * @apiNote The resulting var handle features certain <i>access mode restrictions</i>,
8010      * which are common to all memory segment view var handles. A memory segment view var handle is associated
8011      * with an access size {@code S} and an alignment constraint {@code B}
8012      * (both expressed in bytes). We say that a memory access operation is <em>fully aligned</em> if it occurs
8013      * at a memory address {@code A} which is compatible with both alignment constraints {@code S} and {@code B}.
8014      * If access is fully aligned then following access modes are supported and are
8015      * guaranteed to support atomic access:
8016      * <ul>
8017      * <li>read write access modes for all {@code T}, with the exception of
8018      *     access modes {@code get} and {@code set} for {@code long} and
8019      *     {@code double} on 32-bit platforms.
8020      * <li>atomic update access modes for {@code int}, {@code long},
8021      *     {@code float}, {@code double} or {@link MemorySegment}.
8022      *     (Future major platform releases of the JDK may support additional
8023      *     types for certain currently unsupported access modes.)
8024      * <li>numeric atomic update access modes for {@code int}, {@code long} and {@link MemorySegment}.
8025      *     (Future major platform releases of the JDK may support additional
8026      *     numeric types for certain currently unsupported access modes.)
8027      * <li>bitwise atomic update access modes for {@code int}, {@code long} and {@link MemorySegment}.
8028      *     (Future major platform releases of the JDK may support additional
8029      *     numeric types for certain currently unsupported access modes.)
8030      * </ul>
8031      *
8032      * If {@code T} is {@code float}, {@code double} or {@link MemorySegment} then atomic
8033      * update access modes compare values using their bitwise representation
8034      * (see {@link Float#floatToRawIntBits},
8035      * {@link Double#doubleToRawLongBits} and {@link MemorySegment#address()}, respectively).
8036      * <p>
8037      * Alternatively, a memory access operation is <em>partially aligned</em> if it occurs at a memory address {@code A}
8038      * which is only compatible with the alignment constraint {@code B}; in such cases, access for anything other than the
8039      * {@code get} and {@code set} access modes will result in an {@code IllegalStateException}. If access is partially aligned,
8040      * atomic access is only guaranteed with respect to the largest power of two that divides the GCD of {@code A} and {@code S}.
8041      * <p>
8042      * In all other cases, we say that a memory access operation is <em>misaligned</em>; in such cases an
8043      * {@code IllegalStateException} is thrown, irrespective of the access mode being used.
8044      * <p>
8045      * Finally, if {@code T} is {@code MemorySegment} all write access modes throw {@link IllegalArgumentException}
8046      * unless the value to be written is a {@linkplain MemorySegment#isNative() native} memory segment.
8047      *
8048      * @param layout the value layout for which a memory access handle is to be obtained.
8049      * @return the new memory segment view var handle.
8050      * @throws NullPointerException if {@code layout} is {@code null}.
8051      * @see MemoryLayout#varHandle(MemoryLayout.PathElement...)
8052      * @since 19
8053      */
8054     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8055     public static VarHandle memorySegmentViewVarHandle(ValueLayout layout) {
8056         Objects.requireNonNull(layout);
8057         return Utils.makeSegmentViewVarHandle(layout);
8058     }
8059 
8060     /**
8061      * Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.
8062      * <p>
8063      * When calling e.g. {@link VarHandle#set(Object...)} on the resulting var handle, the incoming value (of type {@code T}, where
8064      * {@code T} is the <em>last</em> parameter type of the first filter function) is processed using the first filter and then passed
8065      * to the target var handle.
8066      * Conversely, when calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the return value obtained from
8067      * the target var handle (of type {@code T}, where {@code T} is the <em>last</em> parameter type of the second filter function)
8068      * is processed using the second filter and returned to the caller. More advanced access mode types, such as
8069      * {@link VarHandle.AccessMode#COMPARE_AND_EXCHANGE} might apply both filters at the same time.
8070      * <p>
8071      * For the boxing and unboxing filters to be well-formed, their types must be of the form {@code (A... , S) -> T} and
8072      * {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle. If this is the case,
8073      * the resulting var handle will have type {@code S} and will feature the additional coordinates {@code A...} (which
8074      * will be appended to the coordinates of the target var handle).
8075      * <p>
8076      * If the boxing and unboxing filters throw any checked exceptions when invoked, the resulting var handle will
8077      * throw an {@link IllegalStateException}.
8078      * <p>
8079      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8080      * atomic access guarantees as those featured by the target var handle.
8081      *
8082      * @param target the target var handle
8083      * @param filterToTarget a filter to convert some type {@code S} into the type of {@code target}
8084      * @param filterFromTarget a filter to convert the type of {@code target} to some type {@code S}
8085      * @return an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
8086      * @throws IllegalArgumentException if {@code filterFromTarget} and {@code filterToTarget} are not well-formed, that is, they have types
8087      * other than {@code (A... , S) -> T} and {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle,
8088      * or if it's determined that either {@code filterFromTarget} or {@code filterToTarget} throws any checked exceptions.
8089      * @throws NullPointerException if any of the arguments is {@code null}.
8090      * @since 19
8091      */
8092     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8093     public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
8094         return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
8095     }
8096 
8097     /**
8098      * Adapts a target var handle by pre-processing incoming coordinate values using unary filter functions.
8099      * <p>
8100      * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the incoming coordinate values
8101      * starting at position {@code pos} (of type {@code C1, C2 ... Cn}, where {@code C1, C2 ... Cn} are the return types
8102      * of the unary filter functions) are transformed into new values (of type {@code S1, S2 ... Sn}, where {@code S1, S2 ... Sn} are the
8103      * parameter types of the unary filter functions), and then passed (along with any coordinate that was left unaltered
8104      * by the adaptation) to the target var handle.
8105      * <p>
8106      * For the coordinate filters to be well-formed, their types must be of the form {@code S1 -> T1, S2 -> T1 ... Sn -> Tn},
8107      * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8108      * <p>
8109      * If any of the filters throws a checked exception when invoked, the resulting var handle will
8110      * throw an {@link IllegalStateException}.
8111      * <p>
8112      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8113      * atomic access guarantees as those featured by the target var handle.
8114      *
8115      * @param target the target var handle
8116      * @param pos the position of the first coordinate to be transformed
8117      * @param filters the unary functions which are used to transform coordinates starting at position {@code pos}
8118      * @return an adapter var handle which accepts new coordinate types, applying the provided transformation
8119      * to the new coordinate values.
8120      * @throws IllegalArgumentException if the handles in {@code filters} are not well-formed, that is, they have types
8121      * other than {@code S1 -> T1, S2 -> T2, ... Sn -> Tn} where {@code T1, T2 ... Tn} are the coordinate types starting
8122      * at position {@code pos} of the target var handle, if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8123      * or if more filters are provided than the actual number of coordinate types available starting at {@code pos},
8124      * or if it's determined that any of the filters throws any checked exceptions.
8125      * @throws NullPointerException if any of the arguments is {@code null} or {@code filters} contains {@code null}.
8126      * @since 19
8127      */
8128     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8129     public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) {
8130         return VarHandles.filterCoordinates(target, pos, filters);
8131     }
8132 
8133     /**
8134      * Provides a target var handle with one or more <em>bound coordinates</em>
8135      * in advance of the var handle's invocation. As a consequence, the resulting var handle will feature less
8136      * coordinate types than the target var handle.
8137      * <p>
8138      * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, incoming coordinate values
8139      * are joined with bound coordinate values, and then passed to the target var handle.
8140      * <p>
8141      * For the bound coordinates to be well-formed, their types must be {@code T1, T2 ... Tn },
8142      * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8143      * <p>
8144      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8145      * atomic access guarantees as those featured by the target var handle.
8146      *
8147      * @param target the var handle to invoke after the bound coordinates are inserted
8148      * @param pos the position of the first coordinate to be inserted
8149      * @param values the series of bound coordinates to insert
8150      * @return an adapter var handle which inserts additional coordinates,
8151      *         before calling the target var handle
8152      * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8153      * or if more values are provided than the actual number of coordinate types available starting at {@code pos}.
8154      * @throws ClassCastException if the bound coordinates in {@code values} are not well-formed, that is, they have types
8155      * other than {@code T1, T2 ... Tn }, where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos}
8156      * of the target var handle.
8157      * @throws NullPointerException if any of the arguments is {@code null} or {@code values} contains {@code null}.
8158      * @since 19
8159      */
8160     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8161     public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
8162         return VarHandles.insertCoordinates(target, pos, values);
8163     }
8164 
8165     /**
8166      * Provides a var handle which adapts the coordinate values of the target var handle, by re-arranging them
8167      * so that the new coordinates match the provided ones.
8168      * <p>
8169      * The given array controls the reordering.
8170      * Call {@code #I} the number of incoming coordinates (the value
8171      * {@code newCoordinates.size()}), and call {@code #O} the number
8172      * of outgoing coordinates (the number of coordinates associated with the target var handle).
8173      * Then the length of the reordering array must be {@code #O},
8174      * and each element must be a non-negative number less than {@code #I}.
8175      * For every {@code N} less than {@code #O}, the {@code N}-th
8176      * outgoing coordinate will be taken from the {@code I}-th incoming
8177      * coordinate, where {@code I} is {@code reorder[N]}.
8178      * <p>
8179      * No coordinate value conversions are applied.
8180      * The type of each incoming coordinate, as determined by {@code newCoordinates},
8181      * must be identical to the type of the corresponding outgoing coordinate
8182      * in the target var handle.
8183      * <p>
8184      * The reordering array need not specify an actual permutation.
8185      * An incoming coordinate will be duplicated if its index appears
8186      * more than once in the array, and an incoming coordinate will be dropped
8187      * if its index does not appear in the array.
8188      * <p>
8189      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8190      * atomic access guarantees as those featured by the target var handle.
8191      * @param target the var handle to invoke after the coordinates have been reordered
8192      * @param newCoordinates the new coordinate types
8193      * @param reorder an index array which controls the reordering
8194      * @return an adapter var handle which re-arranges the incoming coordinate values,
8195      * before calling the target var handle
8196      * @throws IllegalArgumentException if the index array length is not equal to
8197      * the number of coordinates of the target var handle, or if any index array element is not a valid index for
8198      * a coordinate of {@code newCoordinates}, or if two corresponding coordinate types in
8199      * the target var handle and in {@code newCoordinates} are not identical.
8200      * @throws NullPointerException if any of the arguments is {@code null} or {@code newCoordinates} contains {@code null}.
8201      * @since 19
8202      */
8203     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8204     public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) {
8205         return VarHandles.permuteCoordinates(target, newCoordinates, reorder);
8206     }
8207 
8208     /**
8209      * Adapts a target var handle by pre-processing
8210      * a sub-sequence of its coordinate values with a filter (a method handle).
8211      * The pre-processed coordinates are replaced by the result (if any) of the
8212      * filter function and the target var handle is then called on the modified (usually shortened)
8213      * coordinate list.
8214      * <p>
8215      * If {@code R} is the return type of the filter, then:
8216      * <ul>
8217      * <li>if {@code R} <em>is not</em> {@code void}, the target var handle must have a coordinate of type {@code R} in
8218      * position {@code pos}. The parameter types of the filter will replace the coordinate type at position {@code pos}
8219      * of the target var handle. When the returned var handle is invoked, it will be as if the filter is invoked first,
8220      * and its result is passed in place of the coordinate at position {@code pos} in a downstream invocation of the
8221      * target var handle.</li>
8222      * <li> if {@code R} <em>is</em> {@code void}, the parameter types (if any) of the filter will be inserted in the
8223      * coordinate type list of the target var handle at position {@code pos}. In this case, when the returned var handle

8225      * downstream invocation of the target var handle.</li>
8226      * </ul>
8227      * <p>
8228      * If any of the filters throws a checked exception when invoked, the resulting var handle will
8229      * throw an {@link IllegalStateException}.
8230      * <p>
8231      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8232      * atomic access guarantees as those featured by the target var handle.
8233      *
8234      * @param target the var handle to invoke after the coordinates have been filtered
8235      * @param pos the position in the coordinate list of the target var handle where the filter is to be inserted
8236      * @param filter the filter method handle
8237      * @return an adapter var handle which filters the incoming coordinate values,
8238      * before calling the target var handle
8239      * @throws IllegalArgumentException if the return type of {@code filter}
8240      * is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
8241      * if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8242      * if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
8243      * or if it's determined that {@code filter} throws any checked exceptions.
8244      * @throws NullPointerException if any of the arguments is {@code null}.
8245      * @since 19
8246      */
8247     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8248     public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) {
8249         return VarHandles.collectCoordinates(target, pos, filter);
8250     }
8251 
8252     /**
8253      * Returns a var handle which will discard some dummy coordinates before delegating to the
8254      * target var handle. As a consequence, the resulting var handle will feature more
8255      * coordinate types than the target var handle.
8256      * <p>
8257      * The {@code pos} argument may range between zero and <i>N</i>, where <i>N</i> is the arity of the
8258      * target var handle's coordinate types. If {@code pos} is zero, the dummy coordinates will precede
8259      * the target's real arguments; if {@code pos} is <i>N</i> they will come after.
8260      * <p>
8261      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8262      * atomic access guarantees as those featured by the target var handle.
8263      *
8264      * @param target the var handle to invoke after the dummy coordinates are dropped
8265      * @param pos position of the first coordinate to drop (zero for the leftmost)
8266      * @param valueTypes the type(s) of the coordinate(s) to drop
8267      * @return an adapter var handle which drops some dummy coordinates,
8268      *         before calling the target var handle
8269      * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive.
8270      * @throws NullPointerException if any of the arguments is {@code null} or {@code valueTypes} contains {@code null}.
8271      * @since 19
8272      */
8273     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8274     public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes) {
8275         return VarHandles.dropCoordinates(target, pos, valueTypes);
8276     }
8277 }

7961     private static MethodType tableSwitchChecks(MethodHandle defaultCase, MethodHandle[] caseActions) {
7962         if (caseActions.length == 0)
7963             throw new IllegalArgumentException("Not enough cases: " + Arrays.toString(caseActions));
7964 
7965         MethodType expectedType = defaultCase.type();
7966 
7967         if (!(expectedType.parameterCount() >= 1) || expectedType.parameterType(0) != int.class)
7968             throw new IllegalArgumentException(
7969                 "Case actions must have int as leading parameter: " + Arrays.toString(caseActions));
7970 
7971         for (MethodHandle mh : caseActions) {
7972             Objects.requireNonNull(mh);
7973             if (mh.type() != expectedType)
7974                 throw new IllegalArgumentException(
7975                     "Case actions must have the same type: " + Arrays.toString(caseActions));
7976         }
7977 
7978         return expectedType;
7979     }
7980 















































































7981     /**
7982      * Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.
7983      * <p>
7984      * When calling e.g. {@link VarHandle#set(Object...)} on the resulting var handle, the incoming value (of type {@code T}, where
7985      * {@code T} is the <em>last</em> parameter type of the first filter function) is processed using the first filter and then passed
7986      * to the target var handle.
7987      * Conversely, when calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the return value obtained from
7988      * the target var handle (of type {@code T}, where {@code T} is the <em>last</em> parameter type of the second filter function)
7989      * is processed using the second filter and returned to the caller. More advanced access mode types, such as
7990      * {@link VarHandle.AccessMode#COMPARE_AND_EXCHANGE} might apply both filters at the same time.
7991      * <p>
7992      * For the boxing and unboxing filters to be well-formed, their types must be of the form {@code (A... , S) -> T} and
7993      * {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle. If this is the case,
7994      * the resulting var handle will have type {@code S} and will feature the additional coordinates {@code A...} (which
7995      * will be appended to the coordinates of the target var handle).
7996      * <p>
7997      * If the boxing and unboxing filters throw any checked exceptions when invoked, the resulting var handle will
7998      * throw an {@link IllegalStateException}.
7999      * <p>
8000      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8001      * atomic access guarantees as those featured by the target var handle.
8002      *
8003      * @param target the target var handle
8004      * @param filterToTarget a filter to convert some type {@code S} into the type of {@code target}
8005      * @param filterFromTarget a filter to convert the type of {@code target} to some type {@code S}
8006      * @return an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
8007      * @throws IllegalArgumentException if {@code filterFromTarget} and {@code filterToTarget} are not well-formed, that is, they have types
8008      * other than {@code (A... , S) -> T} and {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle,
8009      * or if it's determined that either {@code filterFromTarget} or {@code filterToTarget} throws any checked exceptions.
8010      * @throws NullPointerException if any of the arguments is {@code null}.
8011      * @since 22
8012      */

8013     public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
8014         return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
8015     }
8016 
8017     /**
8018      * Adapts a target var handle by pre-processing incoming coordinate values using unary filter functions.
8019      * <p>
8020      * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the incoming coordinate values
8021      * starting at position {@code pos} (of type {@code C1, C2 ... Cn}, where {@code C1, C2 ... Cn} are the return types
8022      * of the unary filter functions) are transformed into new values (of type {@code S1, S2 ... Sn}, where {@code S1, S2 ... Sn} are the
8023      * parameter types of the unary filter functions), and then passed (along with any coordinate that was left unaltered
8024      * by the adaptation) to the target var handle.
8025      * <p>
8026      * For the coordinate filters to be well-formed, their types must be of the form {@code S1 -> T1, S2 -> T1 ... Sn -> Tn},
8027      * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8028      * <p>
8029      * If any of the filters throws a checked exception when invoked, the resulting var handle will
8030      * throw an {@link IllegalStateException}.
8031      * <p>
8032      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8033      * atomic access guarantees as those featured by the target var handle.
8034      *
8035      * @param target the target var handle
8036      * @param pos the position of the first coordinate to be transformed
8037      * @param filters the unary functions which are used to transform coordinates starting at position {@code pos}
8038      * @return an adapter var handle which accepts new coordinate types, applying the provided transformation
8039      * to the new coordinate values.
8040      * @throws IllegalArgumentException if the handles in {@code filters} are not well-formed, that is, they have types
8041      * other than {@code S1 -> T1, S2 -> T2, ... Sn -> Tn} where {@code T1, T2 ... Tn} are the coordinate types starting
8042      * at position {@code pos} of the target var handle, if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8043      * or if more filters are provided than the actual number of coordinate types available starting at {@code pos},
8044      * or if it's determined that any of the filters throws any checked exceptions.
8045      * @throws NullPointerException if any of the arguments is {@code null} or {@code filters} contains {@code null}.
8046      * @since 22
8047      */

8048     public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) {
8049         return VarHandles.filterCoordinates(target, pos, filters);
8050     }
8051 
8052     /**
8053      * Provides a target var handle with one or more <em>bound coordinates</em>
8054      * in advance of the var handle's invocation. As a consequence, the resulting var handle will feature less
8055      * coordinate types than the target var handle.
8056      * <p>
8057      * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, incoming coordinate values
8058      * are joined with bound coordinate values, and then passed to the target var handle.
8059      * <p>
8060      * For the bound coordinates to be well-formed, their types must be {@code T1, T2 ... Tn },
8061      * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8062      * <p>
8063      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8064      * atomic access guarantees as those featured by the target var handle.
8065      *
8066      * @param target the var handle to invoke after the bound coordinates are inserted
8067      * @param pos the position of the first coordinate to be inserted
8068      * @param values the series of bound coordinates to insert
8069      * @return an adapter var handle which inserts additional coordinates,
8070      *         before calling the target var handle
8071      * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8072      * or if more values are provided than the actual number of coordinate types available starting at {@code pos}.
8073      * @throws ClassCastException if the bound coordinates in {@code values} are not well-formed, that is, they have types
8074      * other than {@code T1, T2 ... Tn }, where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos}
8075      * of the target var handle.
8076      * @throws NullPointerException if any of the arguments is {@code null} or {@code values} contains {@code null}.
8077      * @since 22
8078      */

8079     public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
8080         return VarHandles.insertCoordinates(target, pos, values);
8081     }
8082 
8083     /**
8084      * Provides a var handle which adapts the coordinate values of the target var handle, by re-arranging them
8085      * so that the new coordinates match the provided ones.
8086      * <p>
8087      * The given array controls the reordering.
8088      * Call {@code #I} the number of incoming coordinates (the value
8089      * {@code newCoordinates.size()}), and call {@code #O} the number
8090      * of outgoing coordinates (the number of coordinates associated with the target var handle).
8091      * Then the length of the reordering array must be {@code #O},
8092      * and each element must be a non-negative number less than {@code #I}.
8093      * For every {@code N} less than {@code #O}, the {@code N}-th
8094      * outgoing coordinate will be taken from the {@code I}-th incoming
8095      * coordinate, where {@code I} is {@code reorder[N]}.
8096      * <p>
8097      * No coordinate value conversions are applied.
8098      * The type of each incoming coordinate, as determined by {@code newCoordinates},
8099      * must be identical to the type of the corresponding outgoing coordinate
8100      * in the target var handle.
8101      * <p>
8102      * The reordering array need not specify an actual permutation.
8103      * An incoming coordinate will be duplicated if its index appears
8104      * more than once in the array, and an incoming coordinate will be dropped
8105      * if its index does not appear in the array.
8106      * <p>
8107      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8108      * atomic access guarantees as those featured by the target var handle.
8109      * @param target the var handle to invoke after the coordinates have been reordered
8110      * @param newCoordinates the new coordinate types
8111      * @param reorder an index array which controls the reordering
8112      * @return an adapter var handle which re-arranges the incoming coordinate values,
8113      * before calling the target var handle
8114      * @throws IllegalArgumentException if the index array length is not equal to
8115      * the number of coordinates of the target var handle, or if any index array element is not a valid index for
8116      * a coordinate of {@code newCoordinates}, or if two corresponding coordinate types in
8117      * the target var handle and in {@code newCoordinates} are not identical.
8118      * @throws NullPointerException if any of the arguments is {@code null} or {@code newCoordinates} contains {@code null}.
8119      * @since 22
8120      */

8121     public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) {
8122         return VarHandles.permuteCoordinates(target, newCoordinates, reorder);
8123     }
8124 
8125     /**
8126      * Adapts a target var handle by pre-processing
8127      * a sub-sequence of its coordinate values with a filter (a method handle).
8128      * The pre-processed coordinates are replaced by the result (if any) of the
8129      * filter function and the target var handle is then called on the modified (usually shortened)
8130      * coordinate list.
8131      * <p>
8132      * If {@code R} is the return type of the filter, then:
8133      * <ul>
8134      * <li>if {@code R} <em>is not</em> {@code void}, the target var handle must have a coordinate of type {@code R} in
8135      * position {@code pos}. The parameter types of the filter will replace the coordinate type at position {@code pos}
8136      * of the target var handle. When the returned var handle is invoked, it will be as if the filter is invoked first,
8137      * and its result is passed in place of the coordinate at position {@code pos} in a downstream invocation of the
8138      * target var handle.</li>
8139      * <li> if {@code R} <em>is</em> {@code void}, the parameter types (if any) of the filter will be inserted in the
8140      * coordinate type list of the target var handle at position {@code pos}. In this case, when the returned var handle

8142      * downstream invocation of the target var handle.</li>
8143      * </ul>
8144      * <p>
8145      * If any of the filters throws a checked exception when invoked, the resulting var handle will
8146      * throw an {@link IllegalStateException}.
8147      * <p>
8148      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8149      * atomic access guarantees as those featured by the target var handle.
8150      *
8151      * @param target the var handle to invoke after the coordinates have been filtered
8152      * @param pos the position in the coordinate list of the target var handle where the filter is to be inserted
8153      * @param filter the filter method handle
8154      * @return an adapter var handle which filters the incoming coordinate values,
8155      * before calling the target var handle
8156      * @throws IllegalArgumentException if the return type of {@code filter}
8157      * is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
8158      * if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8159      * if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
8160      * or if it's determined that {@code filter} throws any checked exceptions.
8161      * @throws NullPointerException if any of the arguments is {@code null}.
8162      * @since 22
8163      */

8164     public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) {
8165         return VarHandles.collectCoordinates(target, pos, filter);
8166     }
8167 
8168     /**
8169      * Returns a var handle which will discard some dummy coordinates before delegating to the
8170      * target var handle. As a consequence, the resulting var handle will feature more
8171      * coordinate types than the target var handle.
8172      * <p>
8173      * The {@code pos} argument may range between zero and <i>N</i>, where <i>N</i> is the arity of the
8174      * target var handle's coordinate types. If {@code pos} is zero, the dummy coordinates will precede
8175      * the target's real arguments; if {@code pos} is <i>N</i> they will come after.
8176      * <p>
8177      * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8178      * atomic access guarantees as those featured by the target var handle.
8179      *
8180      * @param target the var handle to invoke after the dummy coordinates are dropped
8181      * @param pos position of the first coordinate to drop (zero for the leftmost)
8182      * @param valueTypes the type(s) of the coordinate(s) to drop
8183      * @return an adapter var handle which drops some dummy coordinates,
8184      *         before calling the target var handle
8185      * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive.
8186      * @throws NullPointerException if any of the arguments is {@code null} or {@code valueTypes} contains {@code null}.
8187      * @since 22
8188      */

8189     public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes) {
8190         return VarHandles.dropCoordinates(target, pos, valueTypes);
8191     }
8192 }
< prev index next >