2944 * the {@code Field} object's {@code set} method could return
2945 * normally. In particular, fields which are both {@code static}
2946 * and {@code final} may never be set.
2947 * <p>
2948 * If the field is {@code static}, and
2949 * if the returned method handle is invoked, the field's class will
2950 * be initialized, if it has not already been initialized.
2951 * @param f the reflected field
2952 * @return a method handle which can store values into the reflected field
2953 * @throws IllegalAccessException if access checking fails,
2954 * or if the field is {@code final} and write access
2955 * is not enabled on the {@code Field} object
2956 * @throws NullPointerException if the argument is null
2957 */
2958 public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
2959 return unreflectField(f, true);
2960 }
2961
2962 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
2963 MemberName field = new MemberName(f, isSetter);
2964 if (isSetter && field.isStatic() && field.isFinal())
2965 throw field.makeAccessException("static final field has no write access", this);
2966 assert(isSetter
2967 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
2968 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
2969 @SuppressWarnings("deprecation")
2970 Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
2971 return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
2972 }
2973
2974 /**
2975 * Produces a VarHandle giving access to a reflected field {@code f}
2976 * of type {@code T} declared in a class of type {@code R}.
2977 * The VarHandle's variable type is {@code T}.
2978 * If the field is non-static the VarHandle has one coordinate type,
2979 * {@code R}. Otherwise, the field is static, and the VarHandle has no
2980 * coordinate types.
2981 * <p>
2982 * Access checking is performed immediately on behalf of the lookup
2983 * class, regardless of the value of the field's {@code accessible}
2984 * flag.
2985 * <p>
3506 if (!putField.isFinal()) {
3507 // A VarHandle does not support updates to final fields, any
3508 // such VarHandle to a final field will be read-only and
3509 // therefore the following write-based accessibility checks are
3510 // only required for non-final fields
3511 checkField(putRefKind, refc, putField);
3512 if (checkSecurity)
3513 checkSecurityManager(refc, putField);
3514 }
3515
3516 boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
3517 restrictProtectedReceiver(getField));
3518 if (doRestrict) {
3519 assert !getField.isStatic();
3520 // receiver type of VarHandle is too wide; narrow to caller
3521 if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
3522 throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
3523 }
3524 refc = lookupClass();
3525 }
3526 return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), this.allowedModes == TRUSTED);
3527 }
3528 /** Check access and get the requested constructor. */
3529 private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3530 final boolean checkSecurity = true;
3531 return getDirectConstructorCommon(refc, ctor, checkSecurity);
3532 }
3533 /** Check access and get the requested constructor, eliding security manager checks. */
3534 private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3535 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
3536 return getDirectConstructorCommon(refc, ctor, checkSecurity);
3537 }
3538 /** Common code for all constructors; do not call directly except from immediately above. */
3539 private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
3540 boolean checkSecurity) throws IllegalAccessException {
3541 assert(ctor.isConstructor());
3542 checkAccess(REF_newInvokeSpecial, refc, ctor);
3543 // Optionally check with the security manager; this isn't needed for unreflect* calls.
3544 if (checkSecurity)
3545 checkSecurityManager(refc, ctor);
3546 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
|
2944 * the {@code Field} object's {@code set} method could return
2945 * normally. In particular, fields which are both {@code static}
2946 * and {@code final} may never be set.
2947 * <p>
2948 * If the field is {@code static}, and
2949 * if the returned method handle is invoked, the field's class will
2950 * be initialized, if it has not already been initialized.
2951 * @param f the reflected field
2952 * @return a method handle which can store values into the reflected field
2953 * @throws IllegalAccessException if access checking fails,
2954 * or if the field is {@code final} and write access
2955 * is not enabled on the {@code Field} object
2956 * @throws NullPointerException if the argument is null
2957 */
2958 public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
2959 return unreflectField(f, true);
2960 }
2961
2962 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
2963 MemberName field = new MemberName(f, isSetter);
2964 if (isSetter && field.isFinal()) {
2965 if (field.isStatic()) {
2966 throw field.makeAccessException("static final field has no write access", this);
2967 } else if (field.getDeclaringClass().isHiddenClass()){
2968 throw field.makeAccessException("final field in a hidden class has no write access", this);
2969 }
2970 }
2971 assert(isSetter
2972 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
2973 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
2974 @SuppressWarnings("deprecation")
2975 Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
2976 return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
2977 }
2978
2979 /**
2980 * Produces a VarHandle giving access to a reflected field {@code f}
2981 * of type {@code T} declared in a class of type {@code R}.
2982 * The VarHandle's variable type is {@code T}.
2983 * If the field is non-static the VarHandle has one coordinate type,
2984 * {@code R}. Otherwise, the field is static, and the VarHandle has no
2985 * coordinate types.
2986 * <p>
2987 * Access checking is performed immediately on behalf of the lookup
2988 * class, regardless of the value of the field's {@code accessible}
2989 * flag.
2990 * <p>
3511 if (!putField.isFinal()) {
3512 // A VarHandle does not support updates to final fields, any
3513 // such VarHandle to a final field will be read-only and
3514 // therefore the following write-based accessibility checks are
3515 // only required for non-final fields
3516 checkField(putRefKind, refc, putField);
3517 if (checkSecurity)
3518 checkSecurityManager(refc, putField);
3519 }
3520
3521 boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
3522 restrictProtectedReceiver(getField));
3523 if (doRestrict) {
3524 assert !getField.isStatic();
3525 // receiver type of VarHandle is too wide; narrow to caller
3526 if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
3527 throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
3528 }
3529 refc = lookupClass();
3530 }
3531 return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(),
3532 this.allowedModes == TRUSTED && !getField.getDeclaringClass().isHiddenClass());
3533 }
3534 /** Check access and get the requested constructor. */
3535 private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3536 final boolean checkSecurity = true;
3537 return getDirectConstructorCommon(refc, ctor, checkSecurity);
3538 }
3539 /** Check access and get the requested constructor, eliding security manager checks. */
3540 private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
3541 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
3542 return getDirectConstructorCommon(refc, ctor, checkSecurity);
3543 }
3544 /** Common code for all constructors; do not call directly except from immediately above. */
3545 private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
3546 boolean checkSecurity) throws IllegalAccessException {
3547 assert(ctor.isConstructor());
3548 checkAccess(REF_newInvokeSpecial, refc, ctor);
3549 // Optionally check with the security manager; this isn't needed for unreflect* calls.
3550 if (checkSecurity)
3551 checkSecurityManager(refc, ctor);
3552 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
|