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