< prev index next >

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

Print this page

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");
< prev index next >