3038 * @throws NoSuchFieldException if the field does not exist
3039 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
3040 * @throws NullPointerException if any argument is null
3041 * @since 9
3042 */
3043 public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
3044 MemberName getField = resolveOrFail(REF_getField, recv, name, type);
3045 MemberName putField = resolveOrFail(REF_putField, recv, name, type);
3046 return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField);
3047 }
3048
3049 /**
3050 * Produces a method handle giving read access to a static field.
3051 * The type of the method handle will have a return type of the field's
3052 * value type.
3053 * The method handle will take no arguments.
3054 * Access checking is performed immediately on behalf of the lookup class.
3055 * <p>
3056 * If the returned method handle is invoked, the field's class will
3057 * be initialized, if it has not already been initialized.
3058 * @param refc the class or interface from which the method is accessed
3059 * @param name the field's name
3060 * @param type the field's type
3061 * @return a method handle which can load values from the field
3062 * @throws NoSuchFieldException if the field does not exist
3063 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
3064 * @throws NullPointerException if any argument is null
3065 */
3066 public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
3067 MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
3068 return getDirectField(REF_getStatic, refc, field);
3069 }
3070
3071 /**
3072 * Produces a method handle giving write access to a static field.
3073 * The type of the method handle will have a void return type.
3074 * The method handle will take a single
3075 * argument, of the field's value type, the value to be stored.
3076 * Access checking is performed immediately on behalf of the lookup class.
3077 * <p>
3083 * @return a method handle which can store values into the field
3084 * @throws NoSuchFieldException if the field does not exist
3085 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
3086 * or is {@code final}
3087 * @throws NullPointerException if any argument is null
3088 */
3089 public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
3090 MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
3091 return getDirectField(REF_putStatic, refc, field);
3092 }
3093
3094 /**
3095 * Produces a VarHandle giving access to a static field {@code name} of
3096 * type {@code type} declared in a class of type {@code decl}.
3097 * The VarHandle's variable type is {@code type} and it has no
3098 * coordinate types.
3099 * <p>
3100 * Access checking is performed immediately on behalf of the lookup
3101 * class.
3102 * <p>
3103 * If the returned VarHandle is operated on, the declaring class will be
3104 * initialized, if it has not already been initialized.
3105 * <p>
3106 * Certain access modes of the returned VarHandle are unsupported under
3107 * the following conditions:
3108 * <ul>
3109 * <li>if the field is declared {@code final}, then the write, atomic
3110 * update, numeric atomic update, and bitwise atomic update access
3111 * modes are unsupported.
3112 * <li>if the field type is anything other than {@code byte},
3113 * {@code short}, {@code char}, {@code int}, {@code long},
3114 * {@code float}, or {@code double}, then numeric atomic update
3115 * access modes are unsupported.
3116 * <li>if the field type is anything other than {@code boolean},
3117 * {@code byte}, {@code short}, {@code char}, {@code int} or
3118 * {@code long} then bitwise atomic update access modes are
3119 * unsupported.
3120 * </ul>
3121 * <p>
3122 * If the field is declared {@code volatile} then the returned VarHandle
3123 * will override access to the field (effectively ignore the
3124 * {@code volatile} declaration) in accordance to its specified
3125 * access modes.
3126 * <p>
3127 * If the field type is {@code float} or {@code double} then numeric
3128 * and atomic update access modes compare values using their bitwise
3129 * representation (see {@link Float#floatToRawIntBits} and
3130 * {@link Double#doubleToRawLongBits}, respectively).
3131 * @apiNote
3132 * Bitwise comparison of {@code float} values or {@code double} values,
3133 * as performed by the numeric and atomic update access modes, differ
3134 * from the primitive {@code ==} operator and the {@link Float#equals}
3135 * and {@link Double#equals} methods, specifically with respect to
3136 * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
3137 * Care should be taken when performing a compare and set or a compare
3138 * and exchange operation with such values since the operation may
3139 * unexpectedly fail.
3140 * There are many possible NaN values that are considered to be
3141 * {@code NaN} in Java, although no IEEE 754 floating-point operation
3142 * provided by Java can distinguish between them. Operation failure can
3143 * occur if the expected or witness value is a NaN value and it is
3144 * transformed (perhaps in a platform specific manner) into another NaN
3145 * value, and thus has a different bitwise representation (see
3146 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
3147 * details).
3148 * The values {@code -0.0} and {@code +0.0} have different bitwise
3149 * representations but are considered equal when using the primitive
3150 * {@code ==} operator. Operation failure can occur if, for example, a
3373
3374 Class<?> cl = decl;
3375 while ((cl = cl.getSuperclass()) != null) {
3376 if (cl == ctor.getDeclaringClass()) {
3377 return true;
3378 }
3379 }
3380 return false;
3381 }
3382
3383 /**
3384 * Produces a method handle giving read access to a reflected field.
3385 * The type of the method handle will have a return type of the field's
3386 * value type.
3387 * If the field is {@code static}, the method handle will take no arguments.
3388 * Otherwise, its single argument will be the instance containing
3389 * the field.
3390 * If the {@code Field} object's {@code accessible} flag is not set,
3391 * access checking is performed immediately on behalf of the lookup class.
3392 * <p>
3393 * If the field is static, and
3394 * if the returned method handle is invoked, the field's class will
3395 * be initialized, if it has not already been initialized.
3396 * @param f the reflected field
3397 * @return a method handle which can load values from the reflected field
3398 * @throws IllegalAccessException if access checking fails
3399 * @throws NullPointerException if the argument is null
3400 */
3401 public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
3402 return unreflectField(f, false);
3403 }
3404
3405 /**
3406 * Produces a method handle giving write access to a reflected field.
3407 * The type of the method handle will have a void return type.
3408 * If the field is {@code static}, the method handle will take a single
3409 * argument, of the field's value type, the value to be stored.
3410 * Otherwise, the two arguments will be the instance containing
3411 * the field, and the value to be stored.
3412 * If the {@code Field} object's {@code accessible} flag is not set,
3413 * access checking is performed immediately on behalf of the lookup class.
3414 * <p>
3415 * If the field is {@code final}, write access will not be
3428 * @throws IllegalAccessException if access checking fails,
3429 * or if the field is {@code final} and write access
3430 * is not enabled on the {@code Field} object
3431 * @throws NullPointerException if the argument is null
3432 * @see <a href="{@docRoot}/java.base/java/lang/reflect/doc-files/MutationMethods.html">Mutation methods</a>
3433 */
3434 public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
3435 return unreflectField(f, true);
3436 }
3437
3438 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
3439 @SuppressWarnings("deprecation")
3440 boolean isAccessible = f.isAccessible();
3441 MemberName field = new MemberName(f, isSetter);
3442 if (isSetter && field.isFinal()) {
3443 if (field.isTrustedFinalField()) {
3444 String msg = field.isStatic() ? "static final field has no write access"
3445 : "final field has no write access";
3446 throw field.makeAccessException(msg, this);
3447 }
3448 // check if write access to final field allowed
3449 if (!field.isStatic() && isAccessible) {
3450 SharedSecrets.getJavaLangReflectAccess().checkAllowedToUnreflectFinalSetter(lookupClass, f);
3451 }
3452 }
3453 assert(isSetter
3454 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
3455 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
3456 Lookup lookup = isAccessible ? IMPL_LOOKUP : this;
3457 return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
3458 }
3459
3460 /**
3461 * Produces a VarHandle giving access to a reflected field {@code f}
3462 * of type {@code T} declared in a class of type {@code R}.
3463 * The VarHandle's variable type is {@code T}.
3464 * If the field is non-static the VarHandle has one coordinate type,
3465 * {@code R}. Otherwise, the field is static, and the VarHandle has no
3466 * coordinate types.
3467 * <p>
3468 * Access checking is performed immediately on behalf of the lookup
3469 * class, regardless of the value of the field's {@code accessible}
3470 * flag.
3471 * <p>
3472 * If the field is static, and if the returned VarHandle is operated
3473 * on, the field's declaring class will be initialized, if it has not
3474 * already been initialized.
3475 * <p>
3476 * Certain access modes of the returned VarHandle are unsupported under
3477 * the following conditions:
3478 * <ul>
3479 * <li>if the field is declared {@code final}, then the write, atomic
3480 * update, numeric atomic update, and bitwise atomic update access
3481 * modes are unsupported.
3482 * <li>if the field type is anything other than {@code byte},
3483 * {@code short}, {@code char}, {@code int}, {@code long},
3484 * {@code float}, or {@code double} then numeric atomic update
3485 * access modes are unsupported.
3486 * <li>if the field type is anything other than {@code boolean},
3487 * {@code byte}, {@code short}, {@code char}, {@code int} or
3488 * {@code long} then bitwise atomic update access modes are
3489 * unsupported.
3490 * </ul>
3491 * <p>
3492 * If the field is declared {@code volatile} then the returned VarHandle
3493 * will override access to the field (effectively ignore the
3494 * {@code volatile} declaration) in accordance to its specified
3495 * access modes.
3496 * <p>
3497 * If the field type is {@code float} or {@code double} then numeric
3498 * and atomic update access modes compare values using their bitwise
3499 * representation (see {@link Float#floatToRawIntBits} and
3500 * {@link Double#doubleToRawLongBits}, respectively).
3501 * @apiNote
3502 * Bitwise comparison of {@code float} values or {@code double} values,
3503 * as performed by the numeric and atomic update access modes, differ
3504 * from the primitive {@code ==} operator and the {@link Float#equals}
3505 * and {@link Double#equals} methods, specifically with respect to
3506 * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
3507 * Care should be taken when performing a compare and set or a compare
3508 * and exchange operation with such values since the operation may
3509 * unexpectedly fail.
3510 * There are many possible NaN values that are considered to be
3511 * {@code NaN} in Java, although no IEEE 754 floating-point operation
3512 * provided by Java can distinguish between them. Operation failure can
3513 * occur if the expected or witness value is a NaN value and it is
3514 * transformed (perhaps in a platform specific manner) into another NaN
3515 * value, and thus has a different bitwise representation (see
3516 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
3517 * details).
3518 * The values {@code -0.0} and {@code +0.0} have different bitwise
3519 * representations but are considered equal when using the primitive
3520 * {@code ==} operator. Operation failure can occur if, for example, a
3944
3945 if (!putField.isFinal()) {
3946 // A VarHandle does not support updates to final fields, any
3947 // such VarHandle to a final field will be read-only and
3948 // therefore the following write-based accessibility checks are
3949 // only required for non-final fields
3950 checkField(putRefKind, refc, putField);
3951 }
3952
3953 boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
3954 restrictProtectedReceiver(getField));
3955 if (doRestrict) {
3956 assert !getField.isStatic();
3957 // receiver type of VarHandle is too wide; narrow to caller
3958 if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
3959 throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
3960 }
3961 refc = lookupClass();
3962 }
3963 return VarHandles.makeFieldHandle(getField, refc,
3964 this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
3965 }
3966 /** Check access and get the requested constructor. */
3967 private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3968 return getDirectConstructorCommon(refc, ctor);
3969 }
3970 /** Common code for all constructors; do not call directly except from immediately above. */
3971 private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3972 assert(ctor.isConstructor());
3973 checkAccess(REF_newInvokeSpecial, refc, ctor);
3974 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
3975 return DirectMethodHandle.make(ctor).setVarargs(ctor);
3976 }
3977
3978 /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
3979 */
3980 /*non-public*/
3981 MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
3982 throws ReflectiveOperationException {
3983 if (!(type instanceof Class || type instanceof MethodType))
3984 throw new InternalError("unresolved MemberName");
|
3038 * @throws NoSuchFieldException if the field does not exist
3039 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
3040 * @throws NullPointerException if any argument is null
3041 * @since 9
3042 */
3043 public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
3044 MemberName getField = resolveOrFail(REF_getField, recv, name, type);
3045 MemberName putField = resolveOrFail(REF_putField, recv, name, type);
3046 return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField);
3047 }
3048
3049 /**
3050 * Produces a method handle giving read access to a static field.
3051 * The type of the method handle will have a return type of the field's
3052 * value type.
3053 * The method handle will take no arguments.
3054 * Access checking is performed immediately on behalf of the lookup class.
3055 * <p>
3056 * If the returned method handle is invoked, the field's class will
3057 * be initialized, if it has not already been initialized.
3058 * {@link ExceptionInInitializerError} is thrown if invoking the method handle
3059 * provokes the class to be initialized and the initializer fails.
3060 * {@link IllegalStateException} is thrown if the field is a {@linkplain
3061 * Field#isStrictInit() strictly-initialized} static field and the method handle
3062 * is invoked by the thread initializing the field's class before the field has
3063 * been initialized.
3064 * @param refc the class or interface from which the method is accessed
3065 * @param name the field's name
3066 * @param type the field's type
3067 * @return a method handle which can load values from the field
3068 * @throws NoSuchFieldException if the field does not exist
3069 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
3070 * @throws NullPointerException if any argument is null
3071 */
3072 public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
3073 MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
3074 return getDirectField(REF_getStatic, refc, field);
3075 }
3076
3077 /**
3078 * Produces a method handle giving write access to a static field.
3079 * The type of the method handle will have a void return type.
3080 * The method handle will take a single
3081 * argument, of the field's value type, the value to be stored.
3082 * Access checking is performed immediately on behalf of the lookup class.
3083 * <p>
3089 * @return a method handle which can store values into the field
3090 * @throws NoSuchFieldException if the field does not exist
3091 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
3092 * or is {@code final}
3093 * @throws NullPointerException if any argument is null
3094 */
3095 public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
3096 MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
3097 return getDirectField(REF_putStatic, refc, field);
3098 }
3099
3100 /**
3101 * Produces a VarHandle giving access to a static field {@code name} of
3102 * type {@code type} declared in a class of type {@code decl}.
3103 * The VarHandle's variable type is {@code type} and it has no
3104 * coordinate types.
3105 * <p>
3106 * Access checking is performed immediately on behalf of the lookup
3107 * class.
3108 * <p>
3109 * Certain access modes of the returned VarHandle are unsupported under
3110 * the following conditions:
3111 * <ul>
3112 * <li>if the field is declared {@code final}, then the write, atomic
3113 * update, numeric atomic update, and bitwise atomic update access
3114 * modes are unsupported.
3115 * <li>if the field type is anything other than {@code byte},
3116 * {@code short}, {@code char}, {@code int}, {@code long},
3117 * {@code float}, or {@code double}, then numeric atomic update
3118 * access modes are unsupported.
3119 * <li>if the field type is anything other than {@code boolean},
3120 * {@code byte}, {@code short}, {@code char}, {@code int} or
3121 * {@code long} then bitwise atomic update access modes are
3122 * unsupported.
3123 * </ul>
3124 * <p>
3125 * If the field is declared {@code volatile} then the returned VarHandle
3126 * will override access to the field (effectively ignore the
3127 * {@code volatile} declaration) in accordance to its specified
3128 * access modes.
3129 * <p>
3130 * If the field type is {@code float} or {@code double} then numeric
3131 * and atomic update access modes compare values using their bitwise
3132 * representation (see {@link Float#floatToRawIntBits} and
3133 * {@link Double#doubleToRawLongBits}, respectively).
3134 * <p>
3135 * If the returned VarHandle is operated on, the declaring class will be
3136 * initialized, if it has not already been initialized.
3137 * {@link ExceptionInInitializerError} is thrown if operating on the VarHandle
3138 * provokes the class to be initialized and the initializer fails.
3139 * {@link IllegalStateException} is thrown if the field is a {@linkplain
3140 * Field#isStrictInit() strictly-initialized} static field and the VarHandle
3141 * is operated on by the thread initializing the field's class to read the
3142 * field before it has been initialized.
3143 * @apiNote
3144 * Bitwise comparison of {@code float} values or {@code double} values,
3145 * as performed by the numeric and atomic update access modes, differ
3146 * from the primitive {@code ==} operator and the {@link Float#equals}
3147 * and {@link Double#equals} methods, specifically with respect to
3148 * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
3149 * Care should be taken when performing a compare and set or a compare
3150 * and exchange operation with such values since the operation may
3151 * unexpectedly fail.
3152 * There are many possible NaN values that are considered to be
3153 * {@code NaN} in Java, although no IEEE 754 floating-point operation
3154 * provided by Java can distinguish between them. Operation failure can
3155 * occur if the expected or witness value is a NaN value and it is
3156 * transformed (perhaps in a platform specific manner) into another NaN
3157 * value, and thus has a different bitwise representation (see
3158 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
3159 * details).
3160 * The values {@code -0.0} and {@code +0.0} have different bitwise
3161 * representations but are considered equal when using the primitive
3162 * {@code ==} operator. Operation failure can occur if, for example, a
3385
3386 Class<?> cl = decl;
3387 while ((cl = cl.getSuperclass()) != null) {
3388 if (cl == ctor.getDeclaringClass()) {
3389 return true;
3390 }
3391 }
3392 return false;
3393 }
3394
3395 /**
3396 * Produces a method handle giving read access to a reflected field.
3397 * The type of the method handle will have a return type of the field's
3398 * value type.
3399 * If the field is {@code static}, the method handle will take no arguments.
3400 * Otherwise, its single argument will be the instance containing
3401 * the field.
3402 * If the {@code Field} object's {@code accessible} flag is not set,
3403 * access checking is performed immediately on behalf of the lookup class.
3404 * <p>
3405 * If the field is static, and if the returned method handle is invoked, the
3406 * field's class will be initialized, if it has not already been initialized.
3407 * {@link ExceptionInInitializerError} is thrown if invoking the method handle
3408 * provokes the class to be initialized and the initializer fails.
3409 * {@link IllegalStateException} is thrown if the field is a {@linkplain
3410 * Field#isStrictInit() strictly-initialized} static field and the method handle
3411 * is invoked by the thread initializing the field's class before the field has
3412 * been initialized.
3413 * @param f the reflected field
3414 * @return a method handle which can load values from the reflected field
3415 * @throws IllegalAccessException if access checking fails
3416 * @throws NullPointerException if the argument is null
3417 */
3418 public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
3419 return unreflectField(f, false);
3420 }
3421
3422 /**
3423 * Produces a method handle giving write access to a reflected field.
3424 * The type of the method handle will have a void return type.
3425 * If the field is {@code static}, the method handle will take a single
3426 * argument, of the field's value type, the value to be stored.
3427 * Otherwise, the two arguments will be the instance containing
3428 * the field, and the value to be stored.
3429 * If the {@code Field} object's {@code accessible} flag is not set,
3430 * access checking is performed immediately on behalf of the lookup class.
3431 * <p>
3432 * If the field is {@code final}, write access will not be
3445 * @throws IllegalAccessException if access checking fails,
3446 * or if the field is {@code final} and write access
3447 * is not enabled on the {@code Field} object
3448 * @throws NullPointerException if the argument is null
3449 * @see <a href="{@docRoot}/java.base/java/lang/reflect/doc-files/MutationMethods.html">Mutation methods</a>
3450 */
3451 public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
3452 return unreflectField(f, true);
3453 }
3454
3455 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
3456 @SuppressWarnings("deprecation")
3457 boolean isAccessible = f.isAccessible();
3458 MemberName field = new MemberName(f, isSetter);
3459 if (isSetter && field.isFinal()) {
3460 if (field.isTrustedFinalField()) {
3461 String msg = field.isStatic() ? "static final field has no write access"
3462 : "final field has no write access";
3463 throw field.makeAccessException(msg, this);
3464 }
3465 // strictly-initialized finals not trusted finals at this time
3466 if (field.isStrictInit()) {
3467 throw field.makeAccessException("strictly-initialized final field has no write access", this);
3468 }
3469
3470 // check if write access to final field allowed
3471 if (!field.isStatic() && isAccessible) {
3472 SharedSecrets.getJavaLangReflectAccess().checkAllowedToUnreflectFinalSetter(lookupClass, f);
3473 }
3474 }
3475 assert(isSetter
3476 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
3477 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
3478 Lookup lookup = isAccessible ? IMPL_LOOKUP : this;
3479 return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
3480 }
3481
3482 /**
3483 * Produces a VarHandle giving access to a reflected field {@code f}
3484 * of type {@code T} declared in a class of type {@code R}.
3485 * The VarHandle's variable type is {@code T}.
3486 * If the field is non-static the VarHandle has one coordinate type,
3487 * {@code R}. Otherwise, the field is static, and the VarHandle has no
3488 * coordinate types.
3489 * <p>
3490 * Access checking is performed immediately on behalf of the lookup
3491 * class, regardless of the value of the field's {@code accessible}
3492 * flag.
3493 * <p>
3494 * Certain access modes of the returned VarHandle are unsupported under
3495 * the following conditions:
3496 * <ul>
3497 * <li>if the field is declared {@code final}, then the write, atomic
3498 * update, numeric atomic update, and bitwise atomic update access
3499 * modes are unsupported.
3500 * <li>if the field type is anything other than {@code byte},
3501 * {@code short}, {@code char}, {@code int}, {@code long},
3502 * {@code float}, or {@code double} then numeric atomic update
3503 * access modes are unsupported.
3504 * <li>if the field type is anything other than {@code boolean},
3505 * {@code byte}, {@code short}, {@code char}, {@code int} or
3506 * {@code long} then bitwise atomic update access modes are
3507 * unsupported.
3508 * </ul>
3509 * <p>
3510 * If the field is declared {@code volatile} then the returned VarHandle
3511 * will override access to the field (effectively ignore the
3512 * {@code volatile} declaration) in accordance to its specified
3513 * access modes.
3514 * <p>
3515 * If the field type is {@code float} or {@code double} then numeric
3516 * and atomic update access modes compare values using their bitwise
3517 * representation (see {@link Float#floatToRawIntBits} and
3518 * {@link Double#doubleToRawLongBits}, respectively).
3519 * <p>
3520 * If the field is static, and if the returned VarHandle is operated
3521 * on, the field's declaring class will be initialized, if it has not
3522 * already been initialized.
3523 * {@link ExceptionInInitializerError} is thrown if operating on the VarHandle
3524 * provokes the class to be initialized and the initializer fails.
3525 * {@link IllegalStateException} is thrown if the field is a {@linkplain
3526 * Field#isStrictInit() strictly-initialized} static field and the VarHandle
3527 * is operated on by the thread initializing the field's class to read the
3528 * field before it has been initialized.
3529 * @apiNote
3530 * Bitwise comparison of {@code float} values or {@code double} values,
3531 * as performed by the numeric and atomic update access modes, differ
3532 * from the primitive {@code ==} operator and the {@link Float#equals}
3533 * and {@link Double#equals} methods, specifically with respect to
3534 * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
3535 * Care should be taken when performing a compare and set or a compare
3536 * and exchange operation with such values since the operation may
3537 * unexpectedly fail.
3538 * There are many possible NaN values that are considered to be
3539 * {@code NaN} in Java, although no IEEE 754 floating-point operation
3540 * provided by Java can distinguish between them. Operation failure can
3541 * occur if the expected or witness value is a NaN value and it is
3542 * transformed (perhaps in a platform specific manner) into another NaN
3543 * value, and thus has a different bitwise representation (see
3544 * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
3545 * details).
3546 * The values {@code -0.0} and {@code +0.0} have different bitwise
3547 * representations but are considered equal when using the primitive
3548 * {@code ==} operator. Operation failure can occur if, for example, a
3972
3973 if (!putField.isFinal()) {
3974 // A VarHandle does not support updates to final fields, any
3975 // such VarHandle to a final field will be read-only and
3976 // therefore the following write-based accessibility checks are
3977 // only required for non-final fields
3978 checkField(putRefKind, refc, putField);
3979 }
3980
3981 boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
3982 restrictProtectedReceiver(getField));
3983 if (doRestrict) {
3984 assert !getField.isStatic();
3985 // receiver type of VarHandle is too wide; narrow to caller
3986 if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
3987 throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
3988 }
3989 refc = lookupClass();
3990 }
3991 return VarHandles.makeFieldHandle(getField, refc,
3992 this.allowedModes == TRUSTED);
3993 }
3994 /** Check access and get the requested constructor. */
3995 private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3996 return getDirectConstructorCommon(refc, ctor);
3997 }
3998 /** Common code for all constructors; do not call directly except from immediately above. */
3999 private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4000 assert(ctor.isConstructor());
4001 checkAccess(REF_newInvokeSpecial, refc, ctor);
4002 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
4003 return DirectMethodHandle.make(ctor).setVarargs(ctor);
4004 }
4005
4006 /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4007 */
4008 /*non-public*/
4009 MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4010 throws ReflectiveOperationException {
4011 if (!(type instanceof Class || type instanceof MethodType))
4012 throw new InternalError("unresolved MemberName");
|