< prev index next >

src/java.base/share/classes/java/lang/reflect/Field.java

Print this page

  56  * @see Member
  57  * @see java.lang.Class
  58  * @see java.lang.Class#getFields()
  59  * @see java.lang.Class#getField(String)
  60  * @see java.lang.Class#getDeclaredFields()
  61  * @see java.lang.Class#getDeclaredField(String)
  62  *
  63  * @author Kenneth Russell
  64  * @author Nakul Saraiya
  65  * @since 1.1
  66  */
  67 public final
  68 class Field extends AccessibleObject implements Member {
  69     private final Class<?>            clazz;
  70     private final int                 slot;
  71     // This is guaranteed to be interned by the VM in the 1.4
  72     // reflection implementation
  73     private final String              name;
  74     private final Class<?>            type;
  75     private final int                 modifiers;
  76     private final boolean             trustedFinal;
  77     // Generics and annotations support
  78     private final transient String    signature;
  79     private final byte[]              annotations;
  80 
  81     /**
  82      * Fields are mutable due to {@link AccessibleObject#setAccessible(boolean)}.
  83      * Thus, we return a new copy of a root each time a field is returned.
  84      * Some lazily initialized immutable states can be stored on root and shared to the copies.
  85      */
  86     private Field root;
  87     private transient volatile FieldRepository genericInfo;
  88     private @Stable FieldAccessor fieldAccessor; // access control enabled
  89     private @Stable FieldAccessor overrideFieldAccessor; // access control suppressed
  90     // End shared states
  91 
  92     // Generics infrastructure
  93 
  94     private String getGenericSignature() {return signature;}
  95 
  96     // Accessor for factory

 106         if (genericInfo == null) {
 107             var root = this.root;
 108             if (root != null) {
 109                 genericInfo = root.getGenericInfo();
 110             } else {
 111                 genericInfo = FieldRepository.make(getGenericSignature(), getFactory());
 112             }
 113             this.genericInfo = genericInfo;
 114         }
 115         return genericInfo;
 116     }
 117 
 118     /**
 119      * Package-private constructor
 120      */
 121     @SuppressWarnings("deprecation")
 122     Field(Class<?> declaringClass,
 123           String name,
 124           Class<?> type,
 125           int modifiers,
 126           boolean trustedFinal,
 127           int slot,
 128           String signature,
 129           byte[] annotations)
 130     {
 131         this.clazz = declaringClass;
 132         this.name = name;
 133         this.type = type;
 134         this.modifiers = modifiers;
 135         this.trustedFinal = trustedFinal;
 136         this.slot = slot;
 137         this.signature = signature;
 138         this.annotations = annotations;
 139     }
 140 
 141     /**
 142      * Package-private routine (exposed to java.lang.Class via
 143      * ReflectAccess) which returns a copy of this Field. The copy's
 144      * "root" field points to this Field.
 145      */
 146     Field copy() {
 147         // This routine enables sharing of FieldAccessor objects
 148         // among Field objects which refer to the same underlying
 149         // method in the VM. (All of this contortion is only necessary
 150         // because of the "accessibility" bit in AccessibleObject,
 151         // which implicitly requires that new java.lang.reflect
 152         // objects be fabricated for each reflective call on Class
 153         // objects.)
 154         if (this.root != null)
 155             throw new IllegalArgumentException("Can not copy a non-root Field");
 156 
 157         Field res = new Field(clazz, name, type, modifiers, trustedFinal, slot, signature, annotations);
 158         res.root = this;
 159         // Might as well eagerly propagate this if already present
 160         res.fieldAccessor = fieldAccessor;
 161         res.overrideFieldAccessor = overrideFieldAccessor;
 162         res.genericInfo = genericInfo;
 163 
 164         return res;
 165     }
 166 
 167     /**
 168      * @throws InaccessibleObjectException {@inheritDoc}
 169      * @throws SecurityException {@inheritDoc}
 170      */
 171     @Override
 172     @CallerSensitive
 173     public void setAccessible(boolean flag) {
 174         AccessibleObject.checkPermission();
 175         if (flag) checkCanSetAccessible(Reflection.getCallerClass());
 176         setAccessible0(flag);
 177     }

 197         return name;
 198     }
 199 
 200     /**
 201      * Returns the Java language modifiers for the field represented
 202      * by this {@code Field} object, as an integer. The {@code Modifier} class should
 203      * be used to decode the modifiers.
 204      *
 205      * @see Modifier
 206      * @see #accessFlags()
 207      * @jls 8.3 Field Declarations
 208      * @jls 9.3 Field (Constant) Declarations
 209      */
 210     public int getModifiers() {
 211         return modifiers;
 212     }
 213 
 214     /**
 215      * {@return an unmodifiable set of the {@linkplain AccessFlag
 216      * access flags} for this field, possibly empty}


 217      * @see #getModifiers()
 218      * @jvms 4.5 Fields
 219      * @since 20
 220      */
 221     @Override
 222     public Set<AccessFlag> accessFlags() {
 223         return AccessFlag.maskToAccessFlags(getModifiers(), AccessFlag.Location.FIELD);


 224     }
 225 
 226     /**
 227      * Returns {@code true} if this field represents an element of
 228      * an enumerated class; returns {@code false} otherwise.
 229      *
 230      * @return {@code true} if and only if this field represents an element of
 231      * an enumerated class.
 232      * @since 1.5
 233      * @jls 8.9.1 Enum Constants
 234      */
 235     public boolean isEnumConstant() {
 236         return (getModifiers() & Modifier.ENUM) != 0;
 237     }
 238 
 239     /**
 240      * Returns {@code true} if this field is a synthetic
 241      * field; returns {@code false} otherwise.
 242      *
 243      * @return true if and only if this field is a synthetic

 754      * <p>If the underlying field is static, the {@code obj} argument is
 755      * ignored; it may be null.
 756      *
 757      * <p>Otherwise the underlying field is an instance field.  If the
 758      * specified object argument is null, the method throws a
 759      * {@code NullPointerException}.  If the specified object argument is not
 760      * an instance of the class or interface declaring the underlying
 761      * field, the method throws an {@code IllegalArgumentException}.
 762      *
 763      * <p>If this {@code Field} object is enforcing Java language access control, and
 764      * the underlying field is inaccessible, the method throws an
 765      * {@code IllegalAccessException}.
 766      *
 767      * <p>If the underlying field is final, this {@code Field} object has
 768      * <em>write</em> access if and only if the following conditions are met:
 769      * <ul>
 770      * <li>{@link #setAccessible(boolean) setAccessible(true)} has succeeded for
 771      *     this {@code Field} object;</li>
 772      * <li>the field is non-static; and</li>
 773      * <li>the field's declaring class is not a {@linkplain Class#isHidden()
 774      *     hidden class}; and</li>


 775      * <li>the field's declaring class is not a {@linkplain Class#isRecord()
 776      *     record class}.</li>
 777      * </ul>
 778      * If any of the above checks is not met, this method throws an
 779      * {@code IllegalAccessException}.
 780      *
 781      * <p> Setting a final field in this way
 782      * is meaningful only during deserialization or reconstruction of
 783      * instances of classes with blank final fields, before they are
 784      * made available for access by other parts of a program. Use in
 785      * any other context may have unpredictable effects, including cases
 786      * in which other parts of a program continue to use the original
 787      * value of this field.
 788      *
 789      * <p>If the underlying field is of a primitive type, an unwrapping
 790      * conversion is attempted to convert the new value to a value of
 791      * a primitive type.  If this attempt fails, the method throws an
 792      * {@code IllegalArgumentException}.
 793      *
 794      * <p>If, after possible unwrapping, the new value cannot be

1211             root.setFieldAccessor(accessor);
1212         }
1213     }
1214 
1215     // Sets the overrideFieldAccessor for this Field object and
1216     // (recursively) its root
1217     private void setOverrideFieldAccessor(FieldAccessor accessor) {
1218         overrideFieldAccessor = accessor;
1219         // Propagate up
1220         Field root = this.root;
1221         if (root != null) {
1222             root.setOverrideFieldAccessor(accessor);
1223         }
1224     }
1225 
1226     @Override
1227     /* package-private */ Field getRoot() {
1228         return root;
1229     }
1230 



1231     /* package-private */ boolean isTrustedFinal() {
1232         return trustedFinal;




1233     }
1234 
1235     /**
1236      * {@inheritDoc}
1237      *
1238      * @throws NullPointerException {@inheritDoc}
1239      * @since 1.5
1240      */
1241     @Override
1242     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1243         Objects.requireNonNull(annotationClass);
1244         return annotationClass.cast(declaredAnnotations().get(annotationClass));
1245     }
1246 
1247     /**
1248      * {@inheritDoc}
1249      *
1250      * @throws NullPointerException {@inheritDoc}
1251      * @since 1.8
1252      */

  56  * @see Member
  57  * @see java.lang.Class
  58  * @see java.lang.Class#getFields()
  59  * @see java.lang.Class#getField(String)
  60  * @see java.lang.Class#getDeclaredFields()
  61  * @see java.lang.Class#getDeclaredField(String)
  62  *
  63  * @author Kenneth Russell
  64  * @author Nakul Saraiya
  65  * @since 1.1
  66  */
  67 public final
  68 class Field extends AccessibleObject implements Member {
  69     private final Class<?>            clazz;
  70     private final int                 slot;
  71     // This is guaranteed to be interned by the VM in the 1.4
  72     // reflection implementation
  73     private final String              name;
  74     private final Class<?>            type;
  75     private final int                 modifiers;
  76     private final int                 flags;
  77     // Generics and annotations support
  78     private final transient String    signature;
  79     private final byte[]              annotations;
  80 
  81     /**
  82      * Fields are mutable due to {@link AccessibleObject#setAccessible(boolean)}.
  83      * Thus, we return a new copy of a root each time a field is returned.
  84      * Some lazily initialized immutable states can be stored on root and shared to the copies.
  85      */
  86     private Field root;
  87     private transient volatile FieldRepository genericInfo;
  88     private @Stable FieldAccessor fieldAccessor; // access control enabled
  89     private @Stable FieldAccessor overrideFieldAccessor; // access control suppressed
  90     // End shared states
  91 
  92     // Generics infrastructure
  93 
  94     private String getGenericSignature() {return signature;}
  95 
  96     // Accessor for factory

 106         if (genericInfo == null) {
 107             var root = this.root;
 108             if (root != null) {
 109                 genericInfo = root.getGenericInfo();
 110             } else {
 111                 genericInfo = FieldRepository.make(getGenericSignature(), getFactory());
 112             }
 113             this.genericInfo = genericInfo;
 114         }
 115         return genericInfo;
 116     }
 117 
 118     /**
 119      * Package-private constructor
 120      */
 121     @SuppressWarnings("deprecation")
 122     Field(Class<?> declaringClass,
 123           String name,
 124           Class<?> type,
 125           int modifiers,
 126           int flags,
 127           int slot,
 128           String signature,
 129           byte[] annotations)
 130     {
 131         this.clazz = declaringClass;
 132         this.name = name;
 133         this.type = type;
 134         this.modifiers = modifiers;
 135         this.flags = flags;
 136         this.slot = slot;
 137         this.signature = signature;
 138         this.annotations = annotations;
 139     }
 140 
 141     /**
 142      * Package-private routine (exposed to java.lang.Class via
 143      * ReflectAccess) which returns a copy of this Field. The copy's
 144      * "root" field points to this Field.
 145      */
 146     Field copy() {
 147         // This routine enables sharing of FieldAccessor objects
 148         // among Field objects which refer to the same underlying
 149         // method in the VM. (All of this contortion is only necessary
 150         // because of the "accessibility" bit in AccessibleObject,
 151         // which implicitly requires that new java.lang.reflect
 152         // objects be fabricated for each reflective call on Class
 153         // objects.)
 154         if (this.root != null)
 155             throw new IllegalArgumentException("Can not copy a non-root Field");
 156 
 157         Field res = new Field(clazz, name, type, modifiers, flags, slot, signature, annotations);
 158         res.root = this;
 159         // Might as well eagerly propagate this if already present
 160         res.fieldAccessor = fieldAccessor;
 161         res.overrideFieldAccessor = overrideFieldAccessor;
 162         res.genericInfo = genericInfo;
 163 
 164         return res;
 165     }
 166 
 167     /**
 168      * @throws InaccessibleObjectException {@inheritDoc}
 169      * @throws SecurityException {@inheritDoc}
 170      */
 171     @Override
 172     @CallerSensitive
 173     public void setAccessible(boolean flag) {
 174         AccessibleObject.checkPermission();
 175         if (flag) checkCanSetAccessible(Reflection.getCallerClass());
 176         setAccessible0(flag);
 177     }

 197         return name;
 198     }
 199 
 200     /**
 201      * Returns the Java language modifiers for the field represented
 202      * by this {@code Field} object, as an integer. The {@code Modifier} class should
 203      * be used to decode the modifiers.
 204      *
 205      * @see Modifier
 206      * @see #accessFlags()
 207      * @jls 8.3 Field Declarations
 208      * @jls 9.3 Field (Constant) Declarations
 209      */
 210     public int getModifiers() {
 211         return modifiers;
 212     }
 213 
 214     /**
 215      * {@return an unmodifiable set of the {@linkplain AccessFlag
 216      * access flags} for this field, possibly empty}
 217      * The {@code AccessFlags} may depend on the class file format version of the class.
 218      *
 219      * @see #getModifiers()
 220      * @jvms 4.5 Fields
 221      * @since 20
 222      */
 223     @Override
 224     public Set<AccessFlag> accessFlags() {
 225         int major = SharedSecrets.getJavaLangAccess().classFileFormatVersion(getDeclaringClass()) & 0xffff;
 226         var cffv = ClassFileFormatVersion.fromMajor(major);
 227         return AccessFlag.maskToAccessFlags(getModifiers(), AccessFlag.Location.FIELD, cffv);
 228     }
 229 
 230     /**
 231      * Returns {@code true} if this field represents an element of
 232      * an enumerated class; returns {@code false} otherwise.
 233      *
 234      * @return {@code true} if and only if this field represents an element of
 235      * an enumerated class.
 236      * @since 1.5
 237      * @jls 8.9.1 Enum Constants
 238      */
 239     public boolean isEnumConstant() {
 240         return (getModifiers() & Modifier.ENUM) != 0;
 241     }
 242 
 243     /**
 244      * Returns {@code true} if this field is a synthetic
 245      * field; returns {@code false} otherwise.
 246      *
 247      * @return true if and only if this field is a synthetic

 758      * <p>If the underlying field is static, the {@code obj} argument is
 759      * ignored; it may be null.
 760      *
 761      * <p>Otherwise the underlying field is an instance field.  If the
 762      * specified object argument is null, the method throws a
 763      * {@code NullPointerException}.  If the specified object argument is not
 764      * an instance of the class or interface declaring the underlying
 765      * field, the method throws an {@code IllegalArgumentException}.
 766      *
 767      * <p>If this {@code Field} object is enforcing Java language access control, and
 768      * the underlying field is inaccessible, the method throws an
 769      * {@code IllegalAccessException}.
 770      *
 771      * <p>If the underlying field is final, this {@code Field} object has
 772      * <em>write</em> access if and only if the following conditions are met:
 773      * <ul>
 774      * <li>{@link #setAccessible(boolean) setAccessible(true)} has succeeded for
 775      *     this {@code Field} object;</li>
 776      * <li>the field is non-static; and</li>
 777      * <li>the field's declaring class is not a {@linkplain Class#isHidden()
 778      *     hidden class};</li>
 779      * <li>the field's declaring class is not a {@linkplain Class#isValue()
 780      *     value class}; and</li>
 781      * <li>the field's declaring class is not a {@linkplain Class#isRecord()
 782      *     record class}.</li>
 783      * </ul>
 784      * If any of the above checks is not met, this method throws an
 785      * {@code IllegalAccessException}.
 786      *
 787      * <p> Setting a final field in this way
 788      * is meaningful only during deserialization or reconstruction of
 789      * instances of classes with blank final fields, before they are
 790      * made available for access by other parts of a program. Use in
 791      * any other context may have unpredictable effects, including cases
 792      * in which other parts of a program continue to use the original
 793      * value of this field.
 794      *
 795      * <p>If the underlying field is of a primitive type, an unwrapping
 796      * conversion is attempted to convert the new value to a value of
 797      * a primitive type.  If this attempt fails, the method throws an
 798      * {@code IllegalArgumentException}.
 799      *
 800      * <p>If, after possible unwrapping, the new value cannot be

1217             root.setFieldAccessor(accessor);
1218         }
1219     }
1220 
1221     // Sets the overrideFieldAccessor for this Field object and
1222     // (recursively) its root
1223     private void setOverrideFieldAccessor(FieldAccessor accessor) {
1224         overrideFieldAccessor = accessor;
1225         // Propagate up
1226         Field root = this.root;
1227         if (root != null) {
1228             root.setOverrideFieldAccessor(accessor);
1229         }
1230     }
1231 
1232     @Override
1233     /* package-private */ Field getRoot() {
1234         return root;
1235     }
1236 
1237     private static final int TRUST_FINAL     = 0x0010;
1238     private static final int NULL_RESTRICTED = 0x0020;
1239 
1240     /* package-private */ boolean isTrustedFinal() {
1241         return (flags & TRUST_FINAL) == TRUST_FINAL;
1242     }
1243 
1244     /* package-private */ boolean isNullRestricted() {
1245         return (flags & NULL_RESTRICTED) == NULL_RESTRICTED;
1246     }
1247 
1248     /**
1249      * {@inheritDoc}
1250      *
1251      * @throws NullPointerException {@inheritDoc}
1252      * @since 1.5
1253      */
1254     @Override
1255     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1256         Objects.requireNonNull(annotationClass);
1257         return annotationClass.cast(declaredAnnotations().get(annotationClass));
1258     }
1259 
1260     /**
1261      * {@inheritDoc}
1262      *
1263      * @throws NullPointerException {@inheritDoc}
1264      * @since 1.8
1265      */
< prev index next >