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 */
|