< prev index next >

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

Print this page

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>

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");

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                 // strictly-initialized finals not trusted finals at this time
3449                 if (field.isStrictInit()) {
3450                     throw field.makeAccessException("strictly-initialized final field has no write access", this);
3451                 }
3452 
3453                 // check if write access to final field allowed
3454                 if (!field.isStatic() && isAccessible) {
3455                     SharedSecrets.getJavaLangReflectAccess().checkAllowedToUnreflectFinalSetter(lookupClass, f);
3456                 }
3457             }
3458             assert(isSetter
3459                     ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
3460                     : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
3461             Lookup lookup = isAccessible ? IMPL_LOOKUP : this;
3462             return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
3463         }
3464 
3465         /**
3466          * Produces a VarHandle giving access to a reflected field {@code f}
3467          * of type {@code T} declared in a class of type {@code R}.
3468          * The VarHandle's variable type is {@code T}.
3469          * If the field is non-static the VarHandle has one coordinate type,
3470          * {@code R}.  Otherwise, the field is static, and the VarHandle has no
3471          * coordinate types.
3472          * <p>

3949 
3950             if (!putField.isFinal()) {
3951                 // A VarHandle does not support updates to final fields, any
3952                 // such VarHandle to a final field will be read-only and
3953                 // therefore the following write-based accessibility checks are
3954                 // only required for non-final fields
3955                 checkField(putRefKind, refc, putField);
3956             }
3957 
3958             boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
3959                                   restrictProtectedReceiver(getField));
3960             if (doRestrict) {
3961                 assert !getField.isStatic();
3962                 // receiver type of VarHandle is too wide; narrow to caller
3963                 if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
3964                     throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
3965                 }
3966                 refc = lookupClass();
3967             }
3968             return VarHandles.makeFieldHandle(getField, refc,
3969                                               this.allowedModes == TRUSTED);
3970         }
3971         /** Check access and get the requested constructor. */
3972         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3973             return getDirectConstructorCommon(refc, ctor);
3974         }
3975         /** Common code for all constructors; do not call directly except from immediately above. */
3976         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3977             assert(ctor.isConstructor());
3978             checkAccess(REF_newInvokeSpecial, refc, ctor);
3979             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
3980             return DirectMethodHandle.make(ctor).setVarargs(ctor);
3981         }
3982 
3983         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
3984          */
3985         /*non-public*/
3986         MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
3987                 throws ReflectiveOperationException {
3988             if (!(type instanceof Class || type instanceof MethodType))
3989                 throw new InternalError("unresolved MemberName");
< prev index next >