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 * @throws SecurityException {@inheritDoc}
170 */
171 @Override
172 @CallerSensitive
173 public void setAccessible(boolean flag) {
174 AccessibleObject.checkPermission();
175 if (flag) checkCanSetAccessible(Reflection.getCallerClass());
176 setAccessible0(flag);
177 }
197 return name;
198 }
199
200 /**
201 * Returns the Java language modifiers for the field represented
202 * by this {@code Field} object, as an integer. The {@code Modifier} class should
203 * be used to decode the modifiers.
204 *
205 * @see Modifier
206 * @see #accessFlags()
207 * @jls 8.3 Field Declarations
208 * @jls 9.3 Field (Constant) Declarations
209 */
210 public int getModifiers() {
211 return modifiers;
212 }
213
214 /**
215 * {@return an unmodifiable set of the {@linkplain AccessFlag
216 * access flags} for this field, possibly empty}
217 * @see #getModifiers()
218 * @jvms 4.5 Fields
219 * @since 20
220 */
221 @Override
222 public Set<AccessFlag> accessFlags() {
223 return AccessFlag.maskToAccessFlags(getModifiers(), AccessFlag.Location.FIELD);
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;
237 }
238
239 /**
240 * Returns {@code true} if this field is a synthetic
241 * field; returns {@code false} otherwise.
242 *
243 * @return true if and only if this field is a synthetic
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}; and</li>
775 * <li>the field's declaring class is not a {@linkplain Class#isRecord()
776 * record class}.</li>
777 * </ul>
778 * If any of the above checks is not met, this method throws an
779 * {@code IllegalAccessException}.
780 *
781 * <p> Setting a final field in this way
782 * is meaningful only during deserialization or reconstruction of
783 * instances of classes with blank final fields, before they are
784 * made available for access by other parts of a program. Use in
785 * any other context may have unpredictable effects, including cases
786 * in which other parts of a program continue to use the original
787 * value of this field.
788 *
789 * <p>If the underlying field is of a primitive type, an unwrapping
790 * conversion is attempted to convert the new value to a value of
791 * a primitive type. If this attempt fails, the method throws an
792 * {@code IllegalArgumentException}.
793 *
794 * <p>If, after possible unwrapping, the new value cannot be
1211 root.setFieldAccessor(accessor);
1212 }
1213 }
1214
1215 // Sets the overrideFieldAccessor for this Field object and
1216 // (recursively) its root
1217 private void setOverrideFieldAccessor(FieldAccessor accessor) {
1218 overrideFieldAccessor = accessor;
1219 // Propagate up
1220 Field root = this.root;
1221 if (root != null) {
1222 root.setOverrideFieldAccessor(accessor);
1223 }
1224 }
1225
1226 @Override
1227 /* package-private */ Field getRoot() {
1228 return root;
1229 }
1230
1231 /* package-private */ boolean isTrustedFinal() {
1232 return trustedFinal;
1233 }
1234
1235 /**
1236 * {@inheritDoc}
1237 *
1238 * @throws NullPointerException {@inheritDoc}
1239 * @since 1.5
1240 */
1241 @Override
1242 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1243 Objects.requireNonNull(annotationClass);
1244 return annotationClass.cast(declaredAnnotations().get(annotationClass));
1245 }
1246
1247 /**
1248 * {@inheritDoc}
1249 *
1250 * @throws NullPointerException {@inheritDoc}
1251 * @since 1.8
1252 */
|
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 * @throws SecurityException {@inheritDoc}
170 */
171 @Override
172 @CallerSensitive
173 public void setAccessible(boolean flag) {
174 AccessibleObject.checkPermission();
175 if (flag) checkCanSetAccessible(Reflection.getCallerClass());
176 setAccessible0(flag);
177 }
197 return name;
198 }
199
200 /**
201 * Returns the Java language modifiers for the field represented
202 * by this {@code Field} object, as an integer. The {@code Modifier} class should
203 * be used to decode the modifiers.
204 *
205 * @see Modifier
206 * @see #accessFlags()
207 * @jls 8.3 Field Declarations
208 * @jls 9.3 Field (Constant) Declarations
209 */
210 public int getModifiers() {
211 return modifiers;
212 }
213
214 /**
215 * {@return an unmodifiable set of the {@linkplain AccessFlag
216 * access flags} for this field, possibly empty}
217 * The {@code AccessFlags} may depend on the class file format version of the class.
218 *
219 * @see #getModifiers()
220 * @jvms 4.5 Fields
221 * @since 20
222 */
223 @Override
224 public Set<AccessFlag> accessFlags() {
225 int major = SharedSecrets.getJavaLangAccess().classFileFormatVersion(getDeclaringClass()) & 0xffff;
226 var cffv = ClassFileFormatVersion.fromMajor(major);
227 return AccessFlag.maskToAccessFlags(getModifiers(), AccessFlag.Location.FIELD, cffv);
228 }
229
230 /**
231 * Returns {@code true} if this field represents an element of
232 * an enumerated class; returns {@code false} otherwise.
233 *
234 * @return {@code true} if and only if this field represents an element of
235 * an enumerated class.
236 * @since 1.5
237 * @jls 8.9.1 Enum Constants
238 */
239 public boolean isEnumConstant() {
240 return (getModifiers() & Modifier.ENUM) != 0;
241 }
242
243 /**
244 * Returns {@code true} if this field is a synthetic
245 * field; returns {@code false} otherwise.
246 *
247 * @return true if and only if this field is a synthetic
758 * <p>If the underlying field is static, the {@code obj} argument is
759 * ignored; it may be null.
760 *
761 * <p>Otherwise the underlying field is an instance field. If the
762 * specified object argument is null, the method throws a
763 * {@code NullPointerException}. If the specified object argument is not
764 * an instance of the class or interface declaring the underlying
765 * field, the method throws an {@code IllegalArgumentException}.
766 *
767 * <p>If this {@code Field} object is enforcing Java language access control, and
768 * the underlying field is inaccessible, the method throws an
769 * {@code IllegalAccessException}.
770 *
771 * <p>If the underlying field is final, this {@code Field} object has
772 * <em>write</em> access if and only if the following conditions are met:
773 * <ul>
774 * <li>{@link #setAccessible(boolean) setAccessible(true)} has succeeded for
775 * this {@code Field} object;</li>
776 * <li>the field is non-static; and</li>
777 * <li>the field's declaring class is not a {@linkplain Class#isHidden()
778 * hidden class};</li>
779 * <li>the field's declaring class is not a {@linkplain Class#isValue()
780 * value class}; and</li>
781 * <li>the field's declaring class is not a {@linkplain Class#isRecord()
782 * record class}.</li>
783 * </ul>
784 * If any of the above checks is not met, this method throws an
785 * {@code IllegalAccessException}.
786 *
787 * <p> Setting a final field in this way
788 * is meaningful only during deserialization or reconstruction of
789 * instances of classes with blank final fields, before they are
790 * made available for access by other parts of a program. Use in
791 * any other context may have unpredictable effects, including cases
792 * in which other parts of a program continue to use the original
793 * value of this field.
794 *
795 * <p>If the underlying field is of a primitive type, an unwrapping
796 * conversion is attempted to convert the new value to a value of
797 * a primitive type. If this attempt fails, the method throws an
798 * {@code IllegalArgumentException}.
799 *
800 * <p>If, after possible unwrapping, the new value cannot be
1217 root.setFieldAccessor(accessor);
1218 }
1219 }
1220
1221 // Sets the overrideFieldAccessor for this Field object and
1222 // (recursively) its root
1223 private void setOverrideFieldAccessor(FieldAccessor accessor) {
1224 overrideFieldAccessor = accessor;
1225 // Propagate up
1226 Field root = this.root;
1227 if (root != null) {
1228 root.setOverrideFieldAccessor(accessor);
1229 }
1230 }
1231
1232 @Override
1233 /* package-private */ Field getRoot() {
1234 return root;
1235 }
1236
1237 private static final int TRUST_FINAL = 0x0010;
1238 private static final int NULL_RESTRICTED = 0x0020;
1239
1240 /* package-private */ boolean isTrustedFinal() {
1241 return (flags & TRUST_FINAL) == TRUST_FINAL;
1242 }
1243
1244 /* package-private */ boolean isNullRestricted() {
1245 return (flags & NULL_RESTRICTED) == NULL_RESTRICTED;
1246 }
1247
1248 /**
1249 * {@inheritDoc}
1250 *
1251 * @throws NullPointerException {@inheritDoc}
1252 * @since 1.5
1253 */
1254 @Override
1255 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1256 Objects.requireNonNull(annotationClass);
1257 return annotationClass.cast(declaredAnnotations().get(annotationClass));
1258 }
1259
1260 /**
1261 * {@inheritDoc}
1262 *
1263 * @throws NullPointerException {@inheritDoc}
1264 * @since 1.8
1265 */
|