< 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      */
 170     @Override
 171     @CallerSensitive
 172     public void setAccessible(boolean flag) {
 173         if (flag) checkCanSetAccessible(Reflection.getCallerClass());
 174         setAccessible0(flag);
 175     }
 176 
 177     @Override

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


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


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

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


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

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



1228     /* package-private */ boolean isTrustedFinal() {
1229         return trustedFinal;




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

  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      */
 170     @Override
 171     @CallerSensitive
 172     public void setAccessible(boolean flag) {
 173         if (flag) checkCanSetAccessible(Reflection.getCallerClass());
 174         setAccessible0(flag);
 175     }
 176 
 177     @Override

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

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

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