< 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     // generic info repository; lazily initialized
  80     private transient volatile FieldRepository genericInfo;
  81     private final byte[]              annotations;
  82     // Cached field accessor created without override
  83     @Stable
  84     private FieldAccessor fieldAccessor;
  85     // Cached field accessor created with override
  86     @Stable
  87     private FieldAccessor overrideFieldAccessor;
  88     // For sharing of FieldAccessors. This branching structure is
  89     // currently only two levels deep (i.e., one root Field and
  90     // potentially many Field objects pointing to it.)
  91     //
  92     // If this branching structure would ever contain cycles, deadlocks can
  93     // occur in annotation code.
  94     private Field               root;
  95 
  96     // Generics infrastructure

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

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


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


 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}; and</li>


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

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



1233     /* package-private */ boolean isTrustedFinal() {
1234         return trustedFinal;




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

  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     // generic info repository; lazily initialized
  80     private transient volatile FieldRepository genericInfo;
  81     private final byte[]              annotations;
  82     // Cached field accessor created without override
  83     @Stable
  84     private FieldAccessor fieldAccessor;
  85     // Cached field accessor created with override
  86     @Stable
  87     private FieldAccessor overrideFieldAccessor;
  88     // For sharing of FieldAccessors. This branching structure is
  89     // currently only two levels deep (i.e., one root Field and
  90     // potentially many Field objects pointing to it.)
  91     //
  92     // If this branching structure would ever contain cycles, deadlocks can
  93     // occur in annotation code.
  94     private Field               root;
  95 
  96     // Generics infrastructure

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

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

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

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