63 * @see Member
64 * @see java.lang.Class
65 * @see java.lang.Class#getFields()
66 * @see java.lang.Class#getField(String)
67 * @see java.lang.Class#getDeclaredFields()
68 * @see java.lang.Class#getDeclaredField(String)
69 *
70 * @author Kenneth Russell
71 * @author Nakul Saraiya
72 * @since 1.1
73 */
74 public final
75 class Field extends AccessibleObject implements Member {
76 private final Class<?> clazz;
77 private final int slot;
78 // This is guaranteed to be interned by the VM in the 1.4
79 // reflection implementation
80 private final String name;
81 private final Class<?> type;
82 private final int modifiers;
83 private final boolean trustedFinal;
84 // Generics and annotations support
85 private final transient String signature;
86 private final byte[] annotations;
87
88 /**
89 * Fields are mutable due to {@link AccessibleObject#setAccessible(boolean)}.
90 * Thus, we return a new copy of a root each time a field is returned.
91 * Some lazily initialized immutable states can be stored on root and shared to the copies.
92 */
93 private Field root;
94 private transient volatile FieldRepository genericInfo;
95 private @Stable FieldAccessor fieldAccessor; // access control enabled
96 private @Stable FieldAccessor overrideFieldAccessor; // access control suppressed
97 // End shared states
98
99 // Generics infrastructure
100
101 private String getGenericSignature() {return signature;}
102
103 // Accessor for factory
113 if (genericInfo == null) {
114 var root = this.root;
115 if (root != null) {
116 genericInfo = root.getGenericInfo();
117 } else {
118 genericInfo = FieldRepository.make(getGenericSignature(), getFactory());
119 }
120 this.genericInfo = genericInfo;
121 }
122 return genericInfo;
123 }
124
125 /**
126 * Package-private constructor
127 */
128 @SuppressWarnings("deprecation")
129 Field(Class<?> declaringClass,
130 String name,
131 Class<?> type,
132 int modifiers,
133 boolean trustedFinal,
134 int slot,
135 String signature,
136 byte[] annotations)
137 {
138 this.clazz = declaringClass;
139 this.name = name;
140 this.type = type;
141 this.modifiers = modifiers;
142 this.trustedFinal = trustedFinal;
143 this.slot = slot;
144 this.signature = signature;
145 this.annotations = annotations;
146 }
147
148 /**
149 * Package-private routine (exposed to java.lang.Class via
150 * ReflectAccess) which returns a copy of this Field. The copy's
151 * "root" field points to this Field.
152 */
153 Field copy() {
154 // This routine enables sharing of FieldAccessor objects
155 // among Field objects which refer to the same underlying
156 // method in the VM. (All of this contortion is only necessary
157 // because of the "accessibility" bit in AccessibleObject,
158 // which implicitly requires that new java.lang.reflect
159 // objects be fabricated for each reflective call on Class
160 // objects.)
161 if (this.root != null)
162 throw new IllegalArgumentException("Can not copy a non-root Field");
163
164 Field res = new Field(clazz, name, type, modifiers, trustedFinal, slot, signature, annotations);
165 res.root = this;
166 // Might as well eagerly propagate this if already present
167 res.fieldAccessor = fieldAccessor;
168 res.overrideFieldAccessor = overrideFieldAccessor;
169 res.genericInfo = genericInfo;
170
171 return res;
172 }
173
174 /**
175 * {@inheritDoc}
176 *
177 * <p>If this reflected object represents a non-final field, and this method is
178 * used to enable access, then both <em>{@linkplain #get(Object) read}</em>
179 * and <em>{@linkplain #set(Object, Object) write}</em> access to the field
180 * are enabled.
181 *
182 * <p>If this reflected object represents a <em>non-modifiable</em> final field
183 * then enabling access only enables read access. Any attempt to {@linkplain
184 * #set(Object, Object) set} the field value throws an {@code
223 return name;
224 }
225
226 /**
227 * Returns the Java language modifiers for the field represented
228 * by this {@code Field} object, as an integer. The {@code Modifier} class should
229 * be used to decode the modifiers.
230 *
231 * @see Modifier
232 * @see #accessFlags()
233 * @jls 8.3 Field Declarations
234 * @jls 9.3 Field (Constant) Declarations
235 */
236 public int getModifiers() {
237 return modifiers;
238 }
239
240 /**
241 * {@return an unmodifiable set of the {@linkplain AccessFlag
242 * access flags} for this field, possibly empty}
243 * @see #getModifiers()
244 * @jvms 4.5 Fields
245 * @since 20
246 */
247 @Override
248 public Set<AccessFlag> accessFlags() {
249 return reflectionFactory.parseAccessFlags(getModifiers(), AccessFlag.Location.FIELD, getDeclaringClass());
250 }
251
252 /**
253 * Returns {@code true} if this field represents an element of
254 * an enumerated class; returns {@code false} otherwise.
255 *
256 * @return {@code true} if and only if this field represents an element of
257 * an enumerated class.
258 * @since 1.5
259 * @jls 8.9.1 Enum Constants
260 */
261 public boolean isEnumConstant() {
262 return (getModifiers() & Modifier.ENUM) != 0;
793 * <p>If the underlying field is final, this {@code Field} object has <em>write</em>
794 * access if and only if all of the following conditions are true, where {@code D} is
795 * the field's {@linkplain #getDeclaringClass() declaring class}:
796 *
797 * <ul>
798 * <li>{@link #setAccessible(boolean) setAccessible(true)} has succeeded for this
799 * {@code Field} object.</li>
800 * <li><a href="doc-files/MutationMethods.html">final field mutation is enabled</a>
801 * for the caller's module.</li>
802 * <li> At least one of the following conditions holds:
803 * <ol type="a">
804 * <li> {@code D} and the caller class are in the same module.</li>
805 * <li> The field is {@code public} and {@code D} is {@code public} in a package
806 * that the module containing {@code D} exports to at least the caller's module.</li>
807 * <li> {@code D} is in a package that is {@linkplain Module#isOpen(String, Module)
808 * open} to the caller's module.</li>
809 * </ol>
810 * </li>
811 * <li>{@code D} is not a {@linkplain Class#isRecord() record class}.</li>
812 * <li>{@code D} is not a {@linkplain Class#isHidden() hidden class}.</li>
813 * <li>The field is non-static.</li>
814 * </ul>
815 *
816 * <p>If any of the above conditions is not met, this method throws an
817 * {@code IllegalAccessException}.
818 *
819 * <p>These conditions are more restrictive than the conditions specified by {@link
820 * #setAccessible(boolean)} to suppress access checks. In particular, updating a
821 * module to export or open a package cannot be used to allow <em>write</em> access
822 * to final fields with the {@code set} methods defined by {@code Field}.
823 * Condition (b) is not met if the module containing {@code D} has been updated with
824 * {@linkplain Module#addExports(String, Module) addExports} to export the package to
825 * the caller's module. Condition (c) is not met if the module containing {@code D}
826 * has been updated with {@linkplain Module#addOpens(String, Module) addOpens} to open
827 * the package to the caller's module.
828 *
829 * <p>This method may be called by <a href="{@docRoot}/../specs/jni/index.html">
830 * JNI code</a> with no caller class on the stack. In that case, and when the
831 * underlying field is final, this {@code Field} object has <em>write</em> access
832 * if and only if all of the following conditions are true, where {@code D} is the
1333 root.setFieldAccessor(accessor);
1334 }
1335 }
1336
1337 // Sets the overrideFieldAccessor for this Field object and
1338 // (recursively) its root
1339 private void setOverrideFieldAccessor(FieldAccessor accessor) {
1340 overrideFieldAccessor = accessor;
1341 // Propagate up
1342 Field root = this.root;
1343 if (root != null) {
1344 root.setOverrideFieldAccessor(accessor);
1345 }
1346 }
1347
1348 @Override
1349 /* package-private */ Field getRoot() {
1350 return root;
1351 }
1352
1353 /* package-private */ boolean isTrustedFinal() {
1354 return trustedFinal;
1355 }
1356
1357 /**
1358 * {@inheritDoc}
1359 *
1360 * @throws NullPointerException {@inheritDoc}
1361 * @since 1.5
1362 */
1363 @Override
1364 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1365 Objects.requireNonNull(annotationClass);
1366 return annotationClass.cast(declaredAnnotations().get(annotationClass));
1367 }
1368
1369 /**
1370 * {@inheritDoc}
1371 *
1372 * @throws NullPointerException {@inheritDoc}
1373 * @since 1.8
1374 */
|
63 * @see Member
64 * @see java.lang.Class
65 * @see java.lang.Class#getFields()
66 * @see java.lang.Class#getField(String)
67 * @see java.lang.Class#getDeclaredFields()
68 * @see java.lang.Class#getDeclaredField(String)
69 *
70 * @author Kenneth Russell
71 * @author Nakul Saraiya
72 * @since 1.1
73 */
74 public final
75 class Field extends AccessibleObject implements Member {
76 private final Class<?> clazz;
77 private final int slot;
78 // This is guaranteed to be interned by the VM in the 1.4
79 // reflection implementation
80 private final String name;
81 private final Class<?> type;
82 private final int modifiers;
83 private final int flags;
84 // Generics and annotations support
85 private final transient String signature;
86 private final byte[] annotations;
87
88 /**
89 * Fields are mutable due to {@link AccessibleObject#setAccessible(boolean)}.
90 * Thus, we return a new copy of a root each time a field is returned.
91 * Some lazily initialized immutable states can be stored on root and shared to the copies.
92 */
93 private Field root;
94 private transient volatile FieldRepository genericInfo;
95 private @Stable FieldAccessor fieldAccessor; // access control enabled
96 private @Stable FieldAccessor overrideFieldAccessor; // access control suppressed
97 // End shared states
98
99 // Generics infrastructure
100
101 private String getGenericSignature() {return signature;}
102
103 // Accessor for factory
113 if (genericInfo == null) {
114 var root = this.root;
115 if (root != null) {
116 genericInfo = root.getGenericInfo();
117 } else {
118 genericInfo = FieldRepository.make(getGenericSignature(), getFactory());
119 }
120 this.genericInfo = genericInfo;
121 }
122 return genericInfo;
123 }
124
125 /**
126 * Package-private constructor
127 */
128 @SuppressWarnings("deprecation")
129 Field(Class<?> declaringClass,
130 String name,
131 Class<?> type,
132 int modifiers,
133 int flags,
134 int slot,
135 String signature,
136 byte[] annotations)
137 {
138 this.clazz = declaringClass;
139 this.name = name;
140 this.type = type;
141 this.modifiers = modifiers;
142 this.flags = flags;
143 this.slot = slot;
144 this.signature = signature;
145 this.annotations = annotations;
146 }
147
148 /**
149 * Package-private routine (exposed to java.lang.Class via
150 * ReflectAccess) which returns a copy of this Field. The copy's
151 * "root" field points to this Field.
152 */
153 Field copy() {
154 // This routine enables sharing of FieldAccessor objects
155 // among Field objects which refer to the same underlying
156 // method in the VM. (All of this contortion is only necessary
157 // because of the "accessibility" bit in AccessibleObject,
158 // which implicitly requires that new java.lang.reflect
159 // objects be fabricated for each reflective call on Class
160 // objects.)
161 if (this.root != null)
162 throw new IllegalArgumentException("Can not copy a non-root Field");
163
164 Field res = new Field(clazz, name, type, modifiers, flags, slot, signature, annotations);
165 res.root = this;
166 // Might as well eagerly propagate this if already present
167 res.fieldAccessor = fieldAccessor;
168 res.overrideFieldAccessor = overrideFieldAccessor;
169 res.genericInfo = genericInfo;
170
171 return res;
172 }
173
174 /**
175 * {@inheritDoc}
176 *
177 * <p>If this reflected object represents a non-final field, and this method is
178 * used to enable access, then both <em>{@linkplain #get(Object) read}</em>
179 * and <em>{@linkplain #set(Object, Object) write}</em> access to the field
180 * are enabled.
181 *
182 * <p>If this reflected object represents a <em>non-modifiable</em> final field
183 * then enabling access only enables read access. Any attempt to {@linkplain
184 * #set(Object, Object) set} the field value throws an {@code
223 return name;
224 }
225
226 /**
227 * Returns the Java language modifiers for the field represented
228 * by this {@code Field} object, as an integer. The {@code Modifier} class should
229 * be used to decode the modifiers.
230 *
231 * @see Modifier
232 * @see #accessFlags()
233 * @jls 8.3 Field Declarations
234 * @jls 9.3 Field (Constant) Declarations
235 */
236 public int getModifiers() {
237 return modifiers;
238 }
239
240 /**
241 * {@return an unmodifiable set of the {@linkplain AccessFlag
242 * access flags} for this field, possibly empty}
243 * The {@code AccessFlags} may depend on the class file format version of the class.
244 *
245 * @see #getModifiers()
246 * @jvms 4.5 Fields
247 * @since 20
248 */
249 @Override
250 public Set<AccessFlag> accessFlags() {
251 return reflectionFactory.parseAccessFlags(getModifiers(), AccessFlag.Location.FIELD, getDeclaringClass());
252 }
253
254 /**
255 * Returns {@code true} if this field represents an element of
256 * an enumerated class; returns {@code false} otherwise.
257 *
258 * @return {@code true} if and only if this field represents an element of
259 * an enumerated class.
260 * @since 1.5
261 * @jls 8.9.1 Enum Constants
262 */
263 public boolean isEnumConstant() {
264 return (getModifiers() & Modifier.ENUM) != 0;
795 * <p>If the underlying field is final, this {@code Field} object has <em>write</em>
796 * access if and only if all of the following conditions are true, where {@code D} is
797 * the field's {@linkplain #getDeclaringClass() declaring class}:
798 *
799 * <ul>
800 * <li>{@link #setAccessible(boolean) setAccessible(true)} has succeeded for this
801 * {@code Field} object.</li>
802 * <li><a href="doc-files/MutationMethods.html">final field mutation is enabled</a>
803 * for the caller's module.</li>
804 * <li> At least one of the following conditions holds:
805 * <ol type="a">
806 * <li> {@code D} and the caller class are in the same module.</li>
807 * <li> The field is {@code public} and {@code D} is {@code public} in a package
808 * that the module containing {@code D} exports to at least the caller's module.</li>
809 * <li> {@code D} is in a package that is {@linkplain Module#isOpen(String, Module)
810 * open} to the caller's module.</li>
811 * </ol>
812 * </li>
813 * <li>{@code D} is not a {@linkplain Class#isRecord() record class}.</li>
814 * <li>{@code D} is not a {@linkplain Class#isHidden() hidden class}.</li>
815 * <li>{@code D} is not a {@linkplain Class#isValue() value class}.</li>
816 * <li>The field is non-static.</li>
817 * </ul>
818 *
819 * <p>If any of the above conditions is not met, this method throws an
820 * {@code IllegalAccessException}.
821 *
822 * <p>These conditions are more restrictive than the conditions specified by {@link
823 * #setAccessible(boolean)} to suppress access checks. In particular, updating a
824 * module to export or open a package cannot be used to allow <em>write</em> access
825 * to final fields with the {@code set} methods defined by {@code Field}.
826 * Condition (b) is not met if the module containing {@code D} has been updated with
827 * {@linkplain Module#addExports(String, Module) addExports} to export the package to
828 * the caller's module. Condition (c) is not met if the module containing {@code D}
829 * has been updated with {@linkplain Module#addOpens(String, Module) addOpens} to open
830 * the package to the caller's module.
831 *
832 * <p>This method may be called by <a href="{@docRoot}/../specs/jni/index.html">
833 * JNI code</a> with no caller class on the stack. In that case, and when the
834 * underlying field is final, this {@code Field} object has <em>write</em> access
835 * if and only if all of the following conditions are true, where {@code D} is the
1336 root.setFieldAccessor(accessor);
1337 }
1338 }
1339
1340 // Sets the overrideFieldAccessor for this Field object and
1341 // (recursively) its root
1342 private void setOverrideFieldAccessor(FieldAccessor accessor) {
1343 overrideFieldAccessor = accessor;
1344 // Propagate up
1345 Field root = this.root;
1346 if (root != null) {
1347 root.setOverrideFieldAccessor(accessor);
1348 }
1349 }
1350
1351 @Override
1352 /* package-private */ Field getRoot() {
1353 return root;
1354 }
1355
1356 private static final int TRUST_FINAL = 0x0010;
1357 private static final int NULL_RESTRICTED = 0x0020;
1358
1359 /* package-private */ boolean isTrustedFinal() {
1360 return (flags & TRUST_FINAL) == TRUST_FINAL;
1361 }
1362
1363 /* package-private */ boolean isNullRestricted() {
1364 return (flags & NULL_RESTRICTED) == NULL_RESTRICTED;
1365 }
1366
1367 /**
1368 * {@inheritDoc}
1369 *
1370 * @throws NullPointerException {@inheritDoc}
1371 * @since 1.5
1372 */
1373 @Override
1374 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1375 Objects.requireNonNull(annotationClass);
1376 return annotationClass.cast(declaredAnnotations().get(annotationClass));
1377 }
1378
1379 /**
1380 * {@inheritDoc}
1381 *
1382 * @throws NullPointerException {@inheritDoc}
1383 * @since 1.8
1384 */
|