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 |