< 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 reflectionFactory.parseAccessFlags(getModifiers(), AccessFlag.Location.FIELD, getDeclaringClass());
 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;

 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         return reflectionFactory.parseAccessFlags(getModifiers(), AccessFlag.Location.FIELD, getDeclaringClass());
 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;

 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};</li>
 775      * <li>the field's declaring class is not a {@linkplain Class#isValue()
 776      *     value 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

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