< prev index next >

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

Print this page




2497             return true;
2498         }
2499         private
2500         MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
2501                 throws ReflectiveOperationException {
2502             if (MethodHandleNatives.refKindIsField(refKind)) {
2503                 return getDirectFieldNoSecurityManager(refKind, defc, member);
2504             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
2505                 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
2506             } else if (refKind == REF_newInvokeSpecial) {
2507                 return getDirectConstructorNoSecurityManager(defc, member);
2508             }
2509             // oops
2510             throw newIllegalArgumentException("bad MethodHandle constant #"+member);
2511         }
2512 
2513         static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
2514     }
2515 
2516     /**
2517      * Produces a method handle constructing arrays of a desired type.

2518      * The return type of the method handle will be the array type.
2519      * The type of its sole argument will be {@code int}, which specifies the size of the array.




2520      * @param arrayClass an array type
2521      * @return a method handle which can create arrays of the given type
2522      * @throws NullPointerException if the argument is {@code null}
2523      * @throws IllegalArgumentException if {@code arrayClass} is not an array type
2524      * @see java.lang.reflect.Array#newInstance(Class, int)

2525      * @since 9
2526      */
2527     public static
2528     MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
2529         if (!arrayClass.isArray()) {
2530             throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
2531         }
2532         MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
2533                 bindTo(arrayClass.getComponentType());
2534         return ani.asType(ani.type().changeReturnType(arrayClass));
2535     }
2536 
2537     /**
2538      * Produces a method handle returning the length of an array.

2539      * The type of the method handle will have {@code int} as return type,
2540      * and its sole argument will be the array type.




2541      * @param arrayClass an array type
2542      * @return a method handle which can retrieve the length of an array of the given array type
2543      * @throws NullPointerException if the argument is {@code null}
2544      * @throws IllegalArgumentException if arrayClass is not an array type

2545      * @since 9
2546      */
2547     public static
2548     MethodHandle arrayLength(Class<?> arrayClass) throws IllegalArgumentException {
2549         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.LENGTH);
2550     }
2551 
2552     /**
2553      * Produces a method handle giving read access to elements of an array.

2554      * The type of the method handle will have a return type of the array's
2555      * element type.  Its first argument will be the array type,
2556      * and the second will be {@code int}.








2557      * @param arrayClass an array type
2558      * @return a method handle which can load values from the given array type
2559      * @throws NullPointerException if the argument is null
2560      * @throws  IllegalArgumentException if arrayClass is not an array type

2561      */
2562     public static
2563     MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
2564         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.GET);
2565     }
2566 
2567     /**
2568      * Produces a method handle giving write access to elements of an array.

2569      * The type of the method handle will have a void return type.
2570      * Its last argument will be the array's element type.
2571      * The first and second arguments will be the array type and int.








2572      * @param arrayClass the class of an array
2573      * @return a method handle which can store values into the array type
2574      * @throws NullPointerException if the argument is null
2575      * @throws IllegalArgumentException if arrayClass is not an array type

2576      */
2577     public static
2578     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
2579         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
2580     }
2581 
2582     /**
2583      * Produces a VarHandle giving access to elements of an array of type
2584      * {@code arrayClass}.  The VarHandle's variable type is the component type
2585      * of {@code arrayClass} and the list of coordinate types is
2586      * {@code (arrayClass, int)}, where the {@code int} coordinate type
2587      * corresponds to an argument that is an index into an array.
2588      * <p>
2589      * Certain access modes of the returned VarHandle are unsupported under
2590      * the following conditions:
2591      * <ul>
2592      * <li>if the component type is anything other than {@code byte},
2593      *     {@code short}, {@code char}, {@code int}, {@code long},
2594      *     {@code float}, or {@code double} then numeric atomic update access
2595      *     modes are unsupported.
2596      * <li>if the field type is anything other than {@code boolean},
2597      *     {@code byte}, {@code short}, {@code char}, {@code int} or
2598      *     {@code long} then bitwise atomic update access modes are
2599      *     unsupported.
2600      * </ul>
2601      * <p>
2602      * If the component type is {@code float} or {@code double} then numeric
2603      * and atomic update access modes compare values using their bitwise
2604      * representation (see {@link Float#floatToRawIntBits} and
2605      * {@link Double#doubleToRawLongBits}, respectively).








2606      * @apiNote
2607      * Bitwise comparison of {@code float} values or {@code double} values,
2608      * as performed by the numeric and atomic update access modes, differ
2609      * from the primitive {@code ==} operator and the {@link Float#equals}
2610      * and {@link Double#equals} methods, specifically with respect to
2611      * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
2612      * Care should be taken when performing a compare and set or a compare
2613      * and exchange operation with such values since the operation may
2614      * unexpectedly fail.
2615      * There are many possible NaN values that are considered to be
2616      * {@code NaN} in Java, although no IEEE 754 floating-point operation
2617      * provided by Java can distinguish between them.  Operation failure can
2618      * occur if the expected or witness value is a NaN value and it is
2619      * transformed (perhaps in a platform specific manner) into another NaN
2620      * value, and thus has a different bitwise representation (see
2621      * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2622      * details).
2623      * The values {@code -0.0} and {@code +0.0} have different bitwise
2624      * representations but are considered equal when using the primitive
2625      * {@code ==} operator.  Operation failure can occur if, for example, a




2497             return true;
2498         }
2499         private
2500         MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
2501                 throws ReflectiveOperationException {
2502             if (MethodHandleNatives.refKindIsField(refKind)) {
2503                 return getDirectFieldNoSecurityManager(refKind, defc, member);
2504             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
2505                 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
2506             } else if (refKind == REF_newInvokeSpecial) {
2507                 return getDirectConstructorNoSecurityManager(defc, member);
2508             }
2509             // oops
2510             throw newIllegalArgumentException("bad MethodHandle constant #"+member);
2511         }
2512 
2513         static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
2514     }
2515 
2516     /**
2517      * Produces a method handle constructing arrays of a desired type,
2518      * as if by the {@code anewarray} bytecode.
2519      * The return type of the method handle will be the array type.
2520      * The type of its sole argument will be {@code int}, which specifies the size of the array.
2521      *
2522      * <p> If the returned method handle is invoked with a negative
2523      * array size, a {@code NegativeArraySizeException} will be thrown.
2524      *
2525      * @param arrayClass an array type
2526      * @return a method handle which can create arrays of the given type
2527      * @throws NullPointerException if the argument is {@code null}
2528      * @throws IllegalArgumentException if {@code arrayClass} is not an array type
2529      * @see java.lang.reflect.Array#newInstance(Class, int)
2530      * @jvms 6.5 {@code anewarray} Instruction
2531      * @since 9
2532      */
2533     public static
2534     MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
2535         if (!arrayClass.isArray()) {
2536             throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
2537         }
2538         MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
2539                 bindTo(arrayClass.getComponentType());
2540         return ani.asType(ani.type().changeReturnType(arrayClass));
2541     }
2542 
2543     /**
2544      * Produces a method handle returning the length of an array,
2545      * as if by the {@code arraylength} bytecode.
2546      * The type of the method handle will have {@code int} as return type,
2547      * and its sole argument will be the array type.
2548      *
2549      * <p> If the returned method handle is invoked with a {@code null}
2550      * array reference, a {@code NullPointerException} will be thrown.
2551      *
2552      * @param arrayClass an array type
2553      * @return a method handle which can retrieve the length of an array of the given array type
2554      * @throws NullPointerException if the argument is {@code null}
2555      * @throws IllegalArgumentException if arrayClass is not an array type
2556      * @jvms 6.5 {@code arraylength} Instruction
2557      * @since 9
2558      */
2559     public static
2560     MethodHandle arrayLength(Class<?> arrayClass) throws IllegalArgumentException {
2561         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.LENGTH);
2562     }
2563 
2564     /**
2565      * Produces a method handle giving read access to elements of an array,
2566      * as if by the {@code aaload} bytecode.
2567      * The type of the method handle will have a return type of the array's
2568      * element type.  Its first argument will be the array type,
2569      * and the second will be {@code int}.
2570      *
2571      * <p> When the returned method handle is invoked,
2572      * the array reference and array index are checked.
2573      * A {@code NullPointerException} will be thrown if the array reference
2574      * is {@code null} and an {@code ArrayIndexOutOfBoundsException} will be
2575      * thrown if the index is negative or if it is greater than or equal to
2576      * the length of the array.
2577      *
2578      * @param arrayClass an array type
2579      * @return a method handle which can load values from the given array type
2580      * @throws NullPointerException if the argument is null
2581      * @throws  IllegalArgumentException if arrayClass is not an array type
2582      * @jvms 6.5 {@code aaload} Instruction
2583      */
2584     public static
2585     MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
2586         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.GET);
2587     }
2588 
2589     /**
2590      * Produces a method handle giving write access to elements of an array,
2591      * as if by the {@code astore} bytecode.
2592      * The type of the method handle will have a void return type.
2593      * Its last argument will be the array's element type.
2594      * The first and second arguments will be the array type and int.
2595      *
2596      * <p> When the returned method handle is invoked,
2597      * the array reference and array index are checked.
2598      * A {@code NullPointerException} will be thrown if the array reference
2599      * is {@code null} and an {@code ArrayIndexOutOfBoundsException} will be
2600      * thrown if the index is negative or if it is greater than or equal to
2601      * the length of the array.
2602      *
2603      * @param arrayClass the class of an array
2604      * @return a method handle which can store values into the array type
2605      * @throws NullPointerException if the argument is null
2606      * @throws IllegalArgumentException if arrayClass is not an array type
2607      * @jvms 6.5 {@code aastore} Instruction
2608      */
2609     public static
2610     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
2611         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
2612     }
2613 
2614     /**
2615      * Produces a VarHandle giving access to elements of an array of type
2616      * {@code arrayClass}.  The VarHandle's variable type is the component type
2617      * of {@code arrayClass} and the list of coordinate types is
2618      * {@code (arrayClass, int)}, where the {@code int} coordinate type
2619      * corresponds to an argument that is an index into an array.
2620      * <p>
2621      * Certain access modes of the returned VarHandle are unsupported under
2622      * the following conditions:
2623      * <ul>
2624      * <li>if the component type is anything other than {@code byte},
2625      *     {@code short}, {@code char}, {@code int}, {@code long},
2626      *     {@code float}, or {@code double} then numeric atomic update access
2627      *     modes are unsupported.
2628      * <li>if the field type is anything other than {@code boolean},
2629      *     {@code byte}, {@code short}, {@code char}, {@code int} or
2630      *     {@code long} then bitwise atomic update access modes are
2631      *     unsupported.
2632      * </ul>
2633      * <p>
2634      * If the component type is {@code float} or {@code double} then numeric
2635      * and atomic update access modes compare values using their bitwise
2636      * representation (see {@link Float#floatToRawIntBits} and
2637      * {@link Double#doubleToRawLongBits}, respectively).
2638      *
2639      * <p> When the returned {@code VarHandle} is invoked,
2640      * the array reference and array index are checked.
2641      * A {@code NullPointerException} will be thrown if the array reference
2642      * is {@code null} and an {@code ArrayIndexOutOfBoundsException} will be
2643      * thrown if the index is negative or if it is greater than or equal to
2644      * the length of the array.
2645      *
2646      * @apiNote
2647      * Bitwise comparison of {@code float} values or {@code double} values,
2648      * as performed by the numeric and atomic update access modes, differ
2649      * from the primitive {@code ==} operator and the {@link Float#equals}
2650      * and {@link Double#equals} methods, specifically with respect to
2651      * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
2652      * Care should be taken when performing a compare and set or a compare
2653      * and exchange operation with such values since the operation may
2654      * unexpectedly fail.
2655      * There are many possible NaN values that are considered to be
2656      * {@code NaN} in Java, although no IEEE 754 floating-point operation
2657      * provided by Java can distinguish between them.  Operation failure can
2658      * occur if the expected or witness value is a NaN value and it is
2659      * transformed (perhaps in a platform specific manner) into another NaN
2660      * value, and thus has a different bitwise representation (see
2661      * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2662      * details).
2663      * The values {@code -0.0} and {@code +0.0} have different bitwise
2664      * representations but are considered equal when using the primitive
2665      * {@code ==} operator.  Operation failure can occur if, for example, a


< prev index next >