< prev index next >

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

Print this page
rev 55127 : 8223351: [lworld] Primary mirror and nullable mirror for inline type
Reviewed-by: tbd


2635      * as if by the {@code astore} bytecode.
2636      * The type of the method handle will have a void return type.
2637      * Its last argument will be the array's element type.
2638      * The first and second arguments will be the array type and int.
2639      *
2640      * <p> When the returned method handle is invoked,
2641      * the array reference and array index are checked.
2642      * A {@code NullPointerException} will be thrown if the array reference
2643      * is {@code null} and an {@code ArrayIndexOutOfBoundsException} will be
2644      * thrown if the index is negative or if it is greater than or equal to
2645      * the length of the array.
2646      *
2647      * @param arrayClass the class of an array
2648      * @return a method handle which can store values into the array type
2649      * @throws NullPointerException if the argument is null
2650      * @throws IllegalArgumentException if arrayClass is not an array type
2651      * @jvms 6.5 {@code aastore} Instruction
2652      */
2653     public static
2654     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
2655         if (arrayClass.isValue()) {
2656             throw new UnsupportedOperationException();
2657         }
2658         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
2659     }
2660 
2661     /**
2662      * Produces a VarHandle giving access to elements of an array of type
2663      * {@code arrayClass}.  The VarHandle's variable type is the component type
2664      * of {@code arrayClass} and the list of coordinate types is
2665      * {@code (arrayClass, int)}, where the {@code int} coordinate type
2666      * corresponds to an argument that is an index into an array.
2667      * <p>
2668      * Certain access modes of the returned VarHandle are unsupported under
2669      * the following conditions:
2670      * <ul>
2671      * <li>if the component type is anything other than {@code byte},
2672      *     {@code short}, {@code char}, {@code int}, {@code long},
2673      *     {@code float}, or {@code double} then numeric atomic update access
2674      *     modes are unsupported.
2675      * <li>if the field type is anything other than {@code boolean},


3412     /**
3413      * Produces a constant method handle of the requested return type which
3414      * returns the default value for that type every time it is invoked.
3415      * The resulting constant method handle will have no side effects.
3416      * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
3417      * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
3418      * since {@code explicitCastArguments} converts {@code null} to default values.
3419      * @param type the expected return type of the desired method handle
3420      * @return a constant method handle that takes no arguments
3421      *         and returns the default value of the given type (or void, if the type is void)
3422      * @throws NullPointerException if the argument is null
3423      * @see MethodHandles#constant
3424      * @see MethodHandles#empty
3425      * @see MethodHandles#explicitCastArguments
3426      * @since 9
3427      */
3428     public static MethodHandle zero(Class<?> type) {
3429         Objects.requireNonNull(type);
3430         if (type.isPrimitive()) {
3431             return zero(Wrapper.forPrimitiveType(type), type);
3432         } else if (type.isValue()) {
3433             throw new UnsupportedOperationException();
3434         } else {
3435             return zero(Wrapper.OBJECT, type);
3436         }
3437     }
3438 
3439     private static MethodHandle identityOrVoid(Class<?> type) {
3440         return type == void.class ? zero(type) : identity(type);
3441     }
3442 
3443     /**
3444      * Produces a method handle of the requested type which ignores any arguments, does nothing,
3445      * and returns a suitable default depending on the return type.
3446      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
3447      * <p>The returned method handle is equivalent to
3448      * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
3449      *
3450      * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
3451      * {@code guardWithTest(pred, target, empty(target.type())}.
3452      * @param type the type of the desired method handle




2635      * as if by the {@code astore} bytecode.
2636      * The type of the method handle will have a void return type.
2637      * Its last argument will be the array's element type.
2638      * The first and second arguments will be the array type and int.
2639      *
2640      * <p> When the returned method handle is invoked,
2641      * the array reference and array index are checked.
2642      * A {@code NullPointerException} will be thrown if the array reference
2643      * is {@code null} and an {@code ArrayIndexOutOfBoundsException} will be
2644      * thrown if the index is negative or if it is greater than or equal to
2645      * the length of the array.
2646      *
2647      * @param arrayClass the class of an array
2648      * @return a method handle which can store values into the array type
2649      * @throws NullPointerException if the argument is null
2650      * @throws IllegalArgumentException if arrayClass is not an array type
2651      * @jvms 6.5 {@code aastore} Instruction
2652      */
2653     public static
2654     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
2655         if (arrayClass.isInlineClass()) {
2656             throw new UnsupportedOperationException();
2657         }
2658         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
2659     }
2660 
2661     /**
2662      * Produces a VarHandle giving access to elements of an array of type
2663      * {@code arrayClass}.  The VarHandle's variable type is the component type
2664      * of {@code arrayClass} and the list of coordinate types is
2665      * {@code (arrayClass, int)}, where the {@code int} coordinate type
2666      * corresponds to an argument that is an index into an array.
2667      * <p>
2668      * Certain access modes of the returned VarHandle are unsupported under
2669      * the following conditions:
2670      * <ul>
2671      * <li>if the component type is anything other than {@code byte},
2672      *     {@code short}, {@code char}, {@code int}, {@code long},
2673      *     {@code float}, or {@code double} then numeric atomic update access
2674      *     modes are unsupported.
2675      * <li>if the field type is anything other than {@code boolean},


3412     /**
3413      * Produces a constant method handle of the requested return type which
3414      * returns the default value for that type every time it is invoked.
3415      * The resulting constant method handle will have no side effects.
3416      * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
3417      * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
3418      * since {@code explicitCastArguments} converts {@code null} to default values.
3419      * @param type the expected return type of the desired method handle
3420      * @return a constant method handle that takes no arguments
3421      *         and returns the default value of the given type (or void, if the type is void)
3422      * @throws NullPointerException if the argument is null
3423      * @see MethodHandles#constant
3424      * @see MethodHandles#empty
3425      * @see MethodHandles#explicitCastArguments
3426      * @since 9
3427      */
3428     public static MethodHandle zero(Class<?> type) {
3429         Objects.requireNonNull(type);
3430         if (type.isPrimitive()) {
3431             return zero(Wrapper.forPrimitiveType(type), type);
3432         } else if (type.isInlineClass()) {
3433             throw new UnsupportedOperationException();
3434         } else {
3435             return zero(Wrapper.OBJECT, type);
3436         }
3437     }
3438 
3439     private static MethodHandle identityOrVoid(Class<?> type) {
3440         return type == void.class ? zero(type) : identity(type);
3441     }
3442 
3443     /**
3444      * Produces a method handle of the requested type which ignores any arguments, does nothing,
3445      * and returns a suitable default depending on the return type.
3446      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
3447      * <p>The returned method handle is equivalent to
3448      * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
3449      *
3450      * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
3451      * {@code guardWithTest(pred, target, empty(target.type())}.
3452      * @param type the type of the desired method handle


< prev index next >