1 /*
2 * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.reflect;
27
28 import java.lang.annotation.Annotation;
29 import java.net.URL;
30 import java.security.CodeSource;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.Objects;
34 import jdk.internal.access.SharedSecrets;
35 import jdk.internal.event.FinalFieldMutationEvent;
36 import jdk.internal.loader.ClassLoaders;
37 import jdk.internal.misc.VM;
38 import jdk.internal.module.ModuleBootstrap;
39 import jdk.internal.module.Modules;
40 import jdk.internal.reflect.CallerSensitive;
41 import jdk.internal.reflect.FieldAccessor;
42 import jdk.internal.reflect.Reflection;
43 import jdk.internal.vm.annotation.ForceInline;
44 import jdk.internal.vm.annotation.Stable;
45 import sun.reflect.generics.repository.FieldRepository;
46 import sun.reflect.generics.factory.CoreReflectionFactory;
47 import sun.reflect.generics.factory.GenericsFactory;
48 import sun.reflect.generics.scope.ClassScope;
49 import sun.reflect.annotation.AnnotationParser;
50 import sun.reflect.annotation.AnnotationSupport;
51 import sun.reflect.annotation.TypeAnnotation;
52 import sun.reflect.annotation.TypeAnnotationParser;
53
54 /**
55 * A {@code Field} provides information about, and dynamic access to, a
56 * single field of a class or an interface. The reflected field may
57 * be a class (static) field or an instance field.
58 *
59 * <p>A {@code Field} permits widening conversions to occur during a get or
60 * set access operation, but throws an {@code IllegalArgumentException} if a
61 * narrowing conversion would occur.
62 *
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
104 private GenericsFactory getFactory() {
105 Class<?> c = getDeclaringClass();
106 // create scope and factory
107 return CoreReflectionFactory.make(c, ClassScope.make(c));
108 }
109
110 // Accessor for generic info repository
111 private FieldRepository getGenericInfo() {
112 var genericInfo = this.genericInfo;
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
185 * IllegalAccessException}. The following fields are non-modifiable:
186 * <ul>
187 * <li>static final fields declared in any class or interface</li>
188 * <li>final fields declared in a {@linkplain Class#isRecord() record}</li>
189 * <li>final fields declared in a {@linkplain Class#isHidden() hidden class}</li>
190 * </ul>
191 * <p>If this reflected object represents a non-static final field in a class that
192 * is not a record class or hidden class, then enabling access will enable read
193 * access. Whether write access is allowed or not is checked when attempting to
194 * {@linkplain #set(Object, Object) set} the field value.
195 *
196 * @throws InaccessibleObjectException {@inheritDoc}
197 */
198 @Override
199 @CallerSensitive
200 public void setAccessible(boolean flag) {
201 if (flag) checkCanSetAccessible(Reflection.getCallerClass());
202 setAccessible0(flag);
203 }
204
205 @Override
206 void checkCanSetAccessible(Class<?> caller) {
207 checkCanSetAccessible(caller, clazz);
208 }
209
210 /**
211 * Returns the {@code Class} object representing the class or interface
212 * that declares the field represented by this {@code Field} object.
213 */
214 @Override
215 public Class<?> getDeclaringClass() {
216 return clazz;
217 }
218
219 /**
220 * Returns the name of the field represented by this {@code Field} object.
221 */
222 public String getName() {
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;
263 }
264
265 /**
266 * Returns {@code true} if this field is a synthetic
267 * field; returns {@code false} otherwise.
268 *
269 * @return true if and only if this field is a synthetic
270 * field as defined by the Java Language Specification.
271 * @since 1.5
272 * @see <a
273 * href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
274 * programming language and JVM modeling in core reflection</a>
275 */
276 public boolean isSynthetic() {
277 return Modifier.isSynthetic(getModifiers());
278 }
279
280 /**
281 * Returns a {@code Class} object that identifies the
282 * declared type for the field represented by this
283 * {@code Field} object.
284 *
285 * @return a {@code Class} object identifying the declared
286 * type of the field represented by this object
287 */
288 public Class<?> getType() {
289 return type;
290 }
291
292 /**
293 * Returns a {@code Type} object that represents the declared type for
294 * the field represented by this {@code Field} object.
295 *
296 * <p>If the declared type of the field is a parameterized type,
297 * the {@code Type} object returned must accurately reflect the
298 * actual type arguments used in the source code.
299 *
300 * <p>If the type of the underlying field is a type variable or a
301 * parameterized type, it is created. Otherwise, it is resolved.
302 *
303 * @return a {@code Type} object that represents the declared type for
304 * the field represented by this {@code Field} object
305 * @throws GenericSignatureFormatError if the generic field
306 * signature does not conform to the format specified in
307 * <cite>The Java Virtual Machine Specification</cite>
308 * @throws TypeNotPresentException if the generic type
309 * signature of the underlying field refers to a non-existent
310 * class or interface declaration
311 * @throws MalformedParameterizedTypeException if the generic
312 * signature of the underlying field refers to a parameterized type
313 * that cannot be instantiated for any reason
314 * @since 1.5
315 */
316 public Type getGenericType() {
317 if (getGenericSignature() != null)
318 return getGenericInfo().getGenericType();
319 else
320 return getType();
321 }
322
323
324 /**
325 * Compares this {@code Field} against the specified object. Returns
326 * true if the objects are the same. Two {@code Field} objects are the same if
327 * they were declared by the same class and have the same name
328 * and type.
329 */
330 public boolean equals(Object obj) {
331 if (obj instanceof Field other) {
332 return (getDeclaringClass() == other.getDeclaringClass())
333 && (getName() == other.getName())
334 && (getType() == other.getType());
335 }
336 return false;
337 }
338
339 /**
340 * Returns a hashcode for this {@code Field}. This is computed as the
341 * exclusive-or of the hashcodes for the underlying field's
342 * declaring class name and its name.
343 */
344 public int hashCode() {
345 return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
346 }
347
348 /**
349 * Returns a string describing this {@code Field}. The format is
350 * the access modifiers for the field, if any, followed
351 * by the field type, followed by a space, followed by
352 * the fully-qualified name of the class declaring the field,
353 * followed by a period, followed by the name of the field.
354 * For example:
355 * <pre>
356 * public static final int java.lang.Thread.MIN_PRIORITY
357 * private int java.io.FileDescriptor.fd
358 * </pre>
359 *
360 * <p>The modifiers are placed in canonical order as specified by
361 * "The Java Language Specification". This is {@code public},
362 * {@code protected} or {@code private} first, and then other
363 * modifiers in the following order: {@code static}, {@code final},
364 * {@code transient}, {@code volatile}.
365 *
366 * @return a string describing this {@code Field}
367 * @jls 8.3.1 Field Modifiers
368 */
369 public String toString() {
370 int mod = getModifiers();
371 return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
372 + getType().getTypeName() + " "
373 + getDeclaringClass().getTypeName() + "."
374 + getName());
375 }
376
377 @Override
378 String toShortString() {
379 return "field " + getDeclaringClass().getTypeName() + "." + getName();
380 }
381
382 /**
383 * Returns a string describing this {@code Field}, including
384 * its generic type. The format is the access modifiers for the
385 * field, if any, followed by the generic field type, followed by
386 * a space, followed by the fully-qualified name of the class
387 * declaring the field, followed by a period, followed by the name
388 * of the field.
389 *
390 * <p>The modifiers are placed in canonical order as specified by
391 * "The Java Language Specification". This is {@code public},
392 * {@code protected} or {@code private} first, and then other
393 * modifiers in the following order: {@code static}, {@code final},
394 * {@code transient}, {@code volatile}.
395 *
396 * @return a string describing this {@code Field}, including
397 * its generic type
398 *
399 * @since 1.5
400 * @jls 8.3.1 Field Modifiers
401 */
402 public String toGenericString() {
403 int mod = getModifiers();
404 Type fieldType = getGenericType();
405 return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
406 + fieldType.getTypeName() + " "
407 + getDeclaringClass().getTypeName() + "."
408 + getName());
409 }
410
411 /**
412 * Returns the value of the field represented by this {@code Field}, on
413 * the specified object. The value is automatically wrapped in an
414 * object if it has a primitive type.
415 *
416 * <p>The underlying field's value is obtained as follows:
417 *
418 * <p>If the underlying field is a static field, the {@code obj} argument
419 * is ignored; it may be null.
420 *
421 * <p>Otherwise, the underlying field is an instance field. If the
422 * specified {@code obj} argument is null, the method throws a
423 * {@code NullPointerException}. If the specified object is not an
424 * instance of the class or interface declaring the underlying
425 * field, the method throws an {@code IllegalArgumentException}.
426 *
427 * <p>If this {@code Field} object is enforcing Java language access control, and
428 * the underlying field is inaccessible, the method throws an
429 * {@code IllegalAccessException}.
430 * If the underlying field is static, the class that declared the
431 * field is initialized if it has not already been initialized.
432 *
433 * <p>Otherwise, the value is retrieved from the underlying instance
434 * or static field. If the field has a primitive type, the value
435 * is wrapped in an object before being returned, otherwise it is
436 * returned as is.
437 *
438 * <p>If the field is hidden in the type of {@code obj},
439 * the field's value is obtained according to the preceding rules.
440 *
441 * @param obj object from which the represented field's value is
442 * to be extracted
443 * @return the value of the represented field in object
444 * {@code obj}; primitive values are wrapped in an appropriate
445 * object before being returned
446 *
447 * @throws IllegalAccessException if this {@code Field} object
448 * is enforcing Java language access control and the underlying
449 * field is inaccessible.
450 * @throws IllegalArgumentException if the specified object is not an
451 * instance of the class or interface declaring the underlying
452 * field (or a subclass or implementor thereof).
453 * @throws NullPointerException if the specified object is null
454 * and the field is an instance field.
455 * @throws ExceptionInInitializerError if the initialization provoked
456 * by this method fails.
457 */
458 @CallerSensitive
459 @ForceInline // to ensure Reflection.getCallerClass optimization
460 public Object get(Object obj)
461 throws IllegalArgumentException, IllegalAccessException
462 {
463 if (!override) {
464 Class<?> caller = Reflection.getCallerClass();
465 checkAccess(caller, obj);
466 return getFieldAccessor().get(obj);
467 } else {
468 return getOverrideFieldAccessor().get(obj);
469 }
470 }
471
472 /**
473 * Gets the value of a static or instance {@code boolean} field.
474 *
475 * @param obj the object to extract the {@code boolean} value
476 * from
477 * @return the value of the {@code boolean} field
478 *
479 * @throws IllegalAccessException if this {@code Field} object
480 * is enforcing Java language access control and the underlying
481 * field is inaccessible.
482 * @throws IllegalArgumentException if the specified object is not
483 * an instance of the class or interface declaring the
484 * underlying field (or a subclass or implementor
485 * thereof), or if the field value cannot be
486 * converted to the type {@code boolean} by a
487 * widening conversion.
488 * @throws NullPointerException if the specified object is null
489 * and the field is an instance field.
490 * @throws ExceptionInInitializerError if the initialization provoked
491 * by this method fails.
492 * @see Field#get
493 */
494 @CallerSensitive
495 @ForceInline // to ensure Reflection.getCallerClass optimization
496 public boolean getBoolean(Object obj)
497 throws IllegalArgumentException, IllegalAccessException
498 {
499 if (!override) {
500 Class<?> caller = Reflection.getCallerClass();
501 checkAccess(caller, obj);
502 return getFieldAccessor().getBoolean(obj);
503 } else {
504 return getOverrideFieldAccessor().getBoolean(obj);
505 }
506 }
507
508 /**
509 * Gets the value of a static or instance {@code byte} field.
510 *
511 * @param obj the object to extract the {@code byte} value
512 * from
513 * @return the value of the {@code byte} field
514 *
515 * @throws IllegalAccessException if this {@code Field} object
516 * is enforcing Java language access control and the underlying
517 * field is inaccessible.
518 * @throws IllegalArgumentException if the specified object is not
519 * an instance of the class or interface declaring the
520 * underlying field (or a subclass or implementor
521 * thereof), or if the field value cannot be
522 * converted to the type {@code byte} by a
523 * widening conversion.
524 * @throws NullPointerException if the specified object is null
525 * and the field is an instance field.
526 * @throws ExceptionInInitializerError if the initialization provoked
527 * by this method fails.
528 * @see Field#get
529 */
530 @CallerSensitive
531 @ForceInline // to ensure Reflection.getCallerClass optimization
532 public byte getByte(Object obj)
533 throws IllegalArgumentException, IllegalAccessException
534 {
535 if (!override) {
536 Class<?> caller = Reflection.getCallerClass();
537 checkAccess(caller, obj);
538 return getFieldAccessor().getByte(obj);
539 } else {
540 return getOverrideFieldAccessor().getByte(obj);
541 }
542 }
543
544 /**
545 * Gets the value of a static or instance field of type
546 * {@code char} or of another primitive type convertible to
547 * type {@code char} via a widening conversion.
548 *
549 * @param obj the object to extract the {@code char} value
550 * from
551 * @return the value of the field converted to type {@code char}
552 *
553 * @throws IllegalAccessException if this {@code Field} object
554 * is enforcing Java language access control and the underlying
555 * field is inaccessible.
556 * @throws IllegalArgumentException if the specified object is not
557 * an instance of the class or interface declaring the
558 * underlying field (or a subclass or implementor
559 * thereof), or if the field value cannot be
560 * converted to the type {@code char} by a
561 * widening conversion.
562 * @throws NullPointerException if the specified object is null
563 * and the field is an instance field.
564 * @throws ExceptionInInitializerError if the initialization provoked
565 * by this method fails.
566 * @see Field#get
567 */
568 @CallerSensitive
569 @ForceInline // to ensure Reflection.getCallerClass optimization
570 public char getChar(Object obj)
571 throws IllegalArgumentException, IllegalAccessException
572 {
573 if (!override) {
574 Class<?> caller = Reflection.getCallerClass();
575 checkAccess(caller, obj);
576 return getFieldAccessor().getChar(obj);
577 } else {
578 return getOverrideFieldAccessor().getChar(obj);
579 }
580 }
581
582 /**
583 * Gets the value of a static or instance field of type
584 * {@code short} or of another primitive type convertible to
585 * type {@code short} via a widening conversion.
586 *
587 * @param obj the object to extract the {@code short} value
588 * from
589 * @return the value of the field converted to type {@code short}
590 *
591 * @throws IllegalAccessException if this {@code Field} object
592 * is enforcing Java language access control and the underlying
593 * field is inaccessible.
594 * @throws IllegalArgumentException if the specified object is not
595 * an instance of the class or interface declaring the
596 * underlying field (or a subclass or implementor
597 * thereof), or if the field value cannot be
598 * converted to the type {@code short} by a
599 * widening conversion.
600 * @throws NullPointerException if the specified object is null
601 * and the field is an instance field.
602 * @throws ExceptionInInitializerError if the initialization provoked
603 * by this method fails.
604 * @see Field#get
605 */
606 @CallerSensitive
607 @ForceInline // to ensure Reflection.getCallerClass optimization
608 public short getShort(Object obj)
609 throws IllegalArgumentException, IllegalAccessException
610 {
611 if (!override) {
612 Class<?> caller = Reflection.getCallerClass();
613 checkAccess(caller, obj);
614 return getFieldAccessor().getShort(obj);
615 } else {
616 return getOverrideFieldAccessor().getShort(obj);
617 }
618 }
619
620 /**
621 * Gets the value of a static or instance field of type
622 * {@code int} or of another primitive type convertible to
623 * type {@code int} via a widening conversion.
624 *
625 * @param obj the object to extract the {@code int} value
626 * from
627 * @return the value of the field converted to type {@code int}
628 *
629 * @throws IllegalAccessException if this {@code Field} object
630 * is enforcing Java language access control and the underlying
631 * field is inaccessible.
632 * @throws IllegalArgumentException if the specified object is not
633 * an instance of the class or interface declaring the
634 * underlying field (or a subclass or implementor
635 * thereof), or if the field value cannot be
636 * converted to the type {@code int} by a
637 * widening conversion.
638 * @throws NullPointerException if the specified object is null
639 * and the field is an instance field.
640 * @throws ExceptionInInitializerError if the initialization provoked
641 * by this method fails.
642 * @see Field#get
643 */
644 @CallerSensitive
645 @ForceInline // to ensure Reflection.getCallerClass optimization
646 public int getInt(Object obj)
647 throws IllegalArgumentException, IllegalAccessException
648 {
649 if (!override) {
650 Class<?> caller = Reflection.getCallerClass();
651 checkAccess(caller, obj);
652 return getFieldAccessor().getInt(obj);
653 } else {
654 return getOverrideFieldAccessor().getInt(obj);
655 }
656 }
657
658 /**
659 * Gets the value of a static or instance field of type
660 * {@code long} or of another primitive type convertible to
661 * type {@code long} via a widening conversion.
662 *
663 * @param obj the object to extract the {@code long} value
664 * from
665 * @return the value of the field converted to type {@code long}
666 *
667 * @throws IllegalAccessException if this {@code Field} object
668 * is enforcing Java language access control and the underlying
669 * field is inaccessible.
670 * @throws IllegalArgumentException if the specified object is not
671 * an instance of the class or interface declaring the
672 * underlying field (or a subclass or implementor
673 * thereof), or if the field value cannot be
674 * converted to the type {@code long} by a
675 * widening conversion.
676 * @throws NullPointerException if the specified object is null
677 * and the field is an instance field.
678 * @throws ExceptionInInitializerError if the initialization provoked
679 * by this method fails.
680 * @see Field#get
681 */
682 @CallerSensitive
683 @ForceInline // to ensure Reflection.getCallerClass optimization
684 public long getLong(Object obj)
685 throws IllegalArgumentException, IllegalAccessException
686 {
687 if (!override) {
688 Class<?> caller = Reflection.getCallerClass();
689 checkAccess(caller, obj);
690 return getFieldAccessor().getLong(obj);
691 } else {
692 return getOverrideFieldAccessor().getLong(obj);
693 }
694 }
695
696 /**
697 * Gets the value of a static or instance field of type
698 * {@code float} or of another primitive type convertible to
699 * type {@code float} via a widening conversion.
700 *
701 * @param obj the object to extract the {@code float} value
702 * from
703 * @return the value of the field converted to type {@code float}
704 *
705 * @throws IllegalAccessException if this {@code Field} object
706 * is enforcing Java language access control and the underlying
707 * field is inaccessible.
708 * @throws IllegalArgumentException if the specified object is not
709 * an instance of the class or interface declaring the
710 * underlying field (or a subclass or implementor
711 * thereof), or if the field value cannot be
712 * converted to the type {@code float} by a
713 * widening conversion.
714 * @throws NullPointerException if the specified object is null
715 * and the field is an instance field.
716 * @throws ExceptionInInitializerError if the initialization provoked
717 * by this method fails.
718 * @see Field#get
719 */
720 @CallerSensitive
721 @ForceInline // to ensure Reflection.getCallerClass optimization
722 public float getFloat(Object obj)
723 throws IllegalArgumentException, IllegalAccessException
724 {
725 if (!override) {
726 Class<?> caller = Reflection.getCallerClass();
727 checkAccess(caller, obj);
728 return getFieldAccessor().getFloat(obj);
729 } else {
730 return getOverrideFieldAccessor().getFloat(obj);
731 }
732 }
733
734 /**
735 * Gets the value of a static or instance field of type
736 * {@code double} or of another primitive type convertible to
737 * type {@code double} via a widening conversion.
738 *
739 * @param obj the object to extract the {@code double} value
740 * from
741 * @return the value of the field converted to type {@code double}
742 *
743 * @throws IllegalAccessException if this {@code Field} object
744 * is enforcing Java language access control and the underlying
745 * field is inaccessible.
746 * @throws IllegalArgumentException if the specified object is not
747 * an instance of the class or interface declaring the
748 * underlying field (or a subclass or implementor
749 * thereof), or if the field value cannot be
750 * converted to the type {@code double} by a
751 * widening conversion.
752 * @throws NullPointerException if the specified object is null
753 * and the field is an instance field.
754 * @throws ExceptionInInitializerError if the initialization provoked
755 * by this method fails.
756 * @see Field#get
757 */
758 @CallerSensitive
759 @ForceInline // to ensure Reflection.getCallerClass optimization
760 public double getDouble(Object obj)
761 throws IllegalArgumentException, IllegalAccessException
762 {
763 if (!override) {
764 Class<?> caller = Reflection.getCallerClass();
765 checkAccess(caller, obj);
766 return getFieldAccessor().getDouble(obj);
767 } else {
768 return getOverrideFieldAccessor().getDouble(obj);
769 }
770 }
771
772 /**
773 * Sets the field represented by this {@code Field} object on the
774 * specified object argument to the specified new value. The new
775 * value is automatically unwrapped if the underlying field has a
776 * primitive type.
777 *
778 * <p>The operation proceeds as follows:
779 *
780 * <p>If the underlying field is static, the {@code obj} argument is
781 * ignored; it may be null.
782 *
783 * <p>Otherwise the underlying field is an instance field. If the
784 * specified object argument is null, the method throws a
785 * {@code NullPointerException}. If the specified object argument is not
786 * an instance of the class or interface declaring the underlying
787 * field, the method throws an {@code IllegalArgumentException}.
788 *
789 * <p>If this {@code Field} object is enforcing Java language access control, and
790 * the underlying field is inaccessible, the method throws an
791 * {@code IllegalAccessException}.
792 *
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
833 * field's {@linkplain #getDeclaringClass() declaring class}:
834 *
835 * <ul>
836 * <li>{@code setAccessible(true)} has succeeded for this {@code Field} object.</li>
837 * <li>final field mutation is enabled for the unnamed module.</li>
838 * <li>The field is {@code public} and {@code D} is {@code public} in a package that
839 * is {@linkplain Module#isExported(String) exported} to all modules.</li>
840 * <li>{@code D} is not a {@linkplain Class#isRecord() record class}.</li>
841 * <li>{@code D} is not a {@linkplain Class#isHidden() hidden class}.</li>
842 * <li>The field is non-static.</li>
843 * </ul>
844 *
845 * <p>If any of the above conditions is not met, this method throws an
846 * {@code IllegalAccessException}.
847 *
848 * <p> Setting a final field in this way
849 * is meaningful only during deserialization or reconstruction of
850 * instances of classes with blank final fields, before they are
851 * made available for access by other parts of a program. Use in
852 * any other context may have unpredictable effects, including cases
853 * in which other parts of a program continue to use the original
854 * value of this field.
855 *
856 * <p>If the underlying field is of a primitive type, an unwrapping
857 * conversion is attempted to convert the new value to a value of
858 * a primitive type. If this attempt fails, the method throws an
859 * {@code IllegalArgumentException}.
860 *
861 * <p>If, after possible unwrapping, the new value cannot be
862 * converted to the type of the underlying field by an identity or
863 * widening conversion, the method throws an
864 * {@code IllegalArgumentException}.
865 *
866 * <p>If the underlying field is static, the class that declared the
867 * field is initialized if it has not already been initialized.
868 *
869 * <p>The field is set to the possibly unwrapped and widened new value.
870 *
871 * <p>If the field is hidden in the type of {@code obj},
872 * the field's value is set according to the preceding rules.
873 *
874 * @param obj the object whose field should be modified
875 * @param value the new value for the field of {@code obj}
876 * being modified
877 *
878 * @throws IllegalAccessException if this {@code Field} object
879 * is enforcing Java language access control and the underlying
880 * field is inaccessible or final;
881 * or if this {@code Field} object has no write access.
882 * @throws IllegalArgumentException if the specified object is not an
883 * instance of the class or interface declaring the underlying
884 * field (or a subclass or implementor thereof),
885 * or if an unwrapping conversion fails.
886 * @throws NullPointerException if the specified object is null
887 * and the field is an instance field.
888 * @throws ExceptionInInitializerError if the initialization provoked
889 * by this method fails.
890 *
891 * @see <a href="doc-files/MutationMethods.html">Mutation methods</a>
892 */
893 @CallerSensitive
894 @ForceInline // to ensure Reflection.getCallerClass optimization
895 public void set(Object obj, Object value)
896 throws IllegalArgumentException, IllegalAccessException
897 {
898 if (!override) {
899 Class<?> caller = Reflection.getCallerClass();
900 checkAccess(caller, obj);
901 getFieldAccessor().set(obj, value);
902 return;
903 }
904
905 FieldAccessor fa = getOverrideFieldAccessor();
906 if (!Modifier.isFinal(modifiers)) {
907 fa.set(obj, value);
908 } else {
909 setFinal(Reflection.getCallerClass(), obj, () -> fa.set(obj, value));
910 }
911 }
912
913 /**
914 * Sets the value of a field as a {@code boolean} on the specified object.
915 * This method is equivalent to
916 * {@code set(obj, zObj)},
917 * where {@code zObj} is a {@code Boolean} object and
918 * {@code zObj.booleanValue() == z}.
919 *
920 * @param obj the object whose field should be modified
921 * @param z the new value for the field of {@code obj}
922 * being modified
923 *
924 * @throws IllegalAccessException if this {@code Field} object
925 * is enforcing Java language access control and the underlying
926 * field is either inaccessible or final;
927 * or if this {@code Field} object has no write access.
928 * @throws IllegalArgumentException if the specified object is not an
929 * instance of the class or interface declaring the underlying
930 * field (or a subclass or implementor thereof),
931 * or if an unwrapping conversion fails.
932 * @throws NullPointerException if the specified object is null
933 * and the field is an instance field.
934 * @throws ExceptionInInitializerError if the initialization provoked
935 * by this method fails.
936 * @see Field#set
937 */
938 @CallerSensitive
939 @ForceInline // to ensure Reflection.getCallerClass optimization
940 public void setBoolean(Object obj, boolean z)
941 throws IllegalArgumentException, IllegalAccessException
942 {
943 if (!override) {
944 Class<?> caller = Reflection.getCallerClass();
945 checkAccess(caller, obj);
946 getFieldAccessor().setBoolean(obj, z);
947 return;
948 }
949
950 FieldAccessor fa = getOverrideFieldAccessor();
951 if (!Modifier.isFinal(modifiers)) {
952 fa.setBoolean(obj, z);
953 } else {
954 setFinal(Reflection.getCallerClass(), obj, () -> fa.setBoolean(obj, z));
955 }
956 }
957
958 /**
959 * Sets the value of a field as a {@code byte} on the specified object.
960 * This method is equivalent to
961 * {@code set(obj, bObj)},
962 * where {@code bObj} is a {@code Byte} object and
963 * {@code bObj.byteValue() == b}.
964 *
965 * @param obj the object whose field should be modified
966 * @param b the new value for the field of {@code obj}
967 * being modified
968 *
969 * @throws IllegalAccessException if this {@code Field} object
970 * is enforcing Java language access control and the underlying
971 * field is either inaccessible or final;
972 * or if this {@code Field} object has no write access.
973 * @throws IllegalArgumentException if the specified object is not an
974 * instance of the class or interface declaring the underlying
975 * field (or a subclass or implementor thereof),
976 * or if an unwrapping conversion fails.
977 * @throws NullPointerException if the specified object is null
978 * and the field is an instance field.
979 * @throws ExceptionInInitializerError if the initialization provoked
980 * by this method fails.
981 * @see Field#set
982 */
983 @CallerSensitive
984 @ForceInline // to ensure Reflection.getCallerClass optimization
985 public void setByte(Object obj, byte b)
986 throws IllegalArgumentException, IllegalAccessException
987 {
988 if (!override) {
989 Class<?> caller = Reflection.getCallerClass();
990 checkAccess(caller, obj);
991 getFieldAccessor().setByte(obj, b);
992 return;
993 }
994
995 FieldAccessor fa = getOverrideFieldAccessor();
996 if (!Modifier.isFinal(modifiers)) {
997 fa.setByte(obj, b);
998 } else {
999 setFinal(Reflection.getCallerClass(), obj, () -> fa.setByte(obj, b));
1000 }
1001 }
1002
1003 /**
1004 * Sets the value of a field as a {@code char} on the specified object.
1005 * This method is equivalent to
1006 * {@code set(obj, cObj)},
1007 * where {@code cObj} is a {@code Character} object and
1008 * {@code cObj.charValue() == c}.
1009 *
1010 * @param obj the object whose field should be modified
1011 * @param c the new value for the field of {@code obj}
1012 * being modified
1013 *
1014 * @throws IllegalAccessException if this {@code Field} object
1015 * is enforcing Java language access control and the underlying
1016 * field is either inaccessible or final;
1017 * or if this {@code Field} object has no write access.
1018 * @throws IllegalArgumentException if the specified object is not an
1019 * instance of the class or interface declaring the underlying
1020 * field (or a subclass or implementor thereof),
1021 * or if an unwrapping conversion fails.
1022 * @throws NullPointerException if the specified object is null
1023 * and the field is an instance field.
1024 * @throws ExceptionInInitializerError if the initialization provoked
1025 * by this method fails.
1026 * @see Field#set
1027 */
1028 @CallerSensitive
1029 @ForceInline // to ensure Reflection.getCallerClass optimization
1030 public void setChar(Object obj, char c)
1031 throws IllegalArgumentException, IllegalAccessException
1032 {
1033 if (!override) {
1034 Class<?> caller = Reflection.getCallerClass();
1035 checkAccess(caller, obj);
1036 getFieldAccessor().setChar(obj, c);
1037 return;
1038 }
1039
1040 FieldAccessor fa = getOverrideFieldAccessor();
1041 if (!Modifier.isFinal(modifiers)) {
1042 fa.setChar(obj, c);
1043 } else {
1044 setFinal(Reflection.getCallerClass(), obj, () -> fa.setChar(obj, c));
1045 }
1046 }
1047
1048 /**
1049 * Sets the value of a field as a {@code short} on the specified object.
1050 * This method is equivalent to
1051 * {@code set(obj, sObj)},
1052 * where {@code sObj} is a {@code Short} object and
1053 * {@code sObj.shortValue() == s}.
1054 *
1055 * @param obj the object whose field should be modified
1056 * @param s the new value for the field of {@code obj}
1057 * being modified
1058 *
1059 * @throws IllegalAccessException if this {@code Field} object
1060 * is enforcing Java language access control and the underlying
1061 * field is either inaccessible or final;
1062 * or if this {@code Field} object has no write access.
1063 * @throws IllegalArgumentException if the specified object is not an
1064 * instance of the class or interface declaring the underlying
1065 * field (or a subclass or implementor thereof),
1066 * or if an unwrapping conversion fails.
1067 * @throws NullPointerException if the specified object is null
1068 * and the field is an instance field.
1069 * @throws ExceptionInInitializerError if the initialization provoked
1070 * by this method fails.
1071 * @see Field#set
1072 */
1073 @CallerSensitive
1074 @ForceInline // to ensure Reflection.getCallerClass optimization
1075 public void setShort(Object obj, short s)
1076 throws IllegalArgumentException, IllegalAccessException
1077 {
1078 if (!override) {
1079 Class<?> caller = Reflection.getCallerClass();
1080 checkAccess(caller, obj);
1081 getFieldAccessor().setShort(obj, s);
1082 return;
1083 }
1084
1085 FieldAccessor fa = getOverrideFieldAccessor();
1086 if (!Modifier.isFinal(modifiers)) {
1087 fa.setShort(obj, s);
1088 } else {
1089 setFinal(Reflection.getCallerClass(), obj, () -> fa.setShort(obj, s));
1090 }
1091 }
1092
1093 /**
1094 * Sets the value of a field as an {@code int} on the specified object.
1095 * This method is equivalent to
1096 * {@code set(obj, iObj)},
1097 * where {@code iObj} is an {@code Integer} object and
1098 * {@code iObj.intValue() == i}.
1099 *
1100 * @param obj the object whose field should be modified
1101 * @param i the new value for the field of {@code obj}
1102 * being modified
1103 *
1104 * @throws IllegalAccessException if this {@code Field} object
1105 * is enforcing Java language access control and the underlying
1106 * field is either inaccessible or final;
1107 * or if this {@code Field} object has no write access.
1108 * @throws IllegalArgumentException if the specified object is not an
1109 * instance of the class or interface declaring the underlying
1110 * field (or a subclass or implementor thereof),
1111 * or if an unwrapping conversion fails.
1112 * @throws NullPointerException if the specified object is null
1113 * and the field is an instance field.
1114 * @throws ExceptionInInitializerError if the initialization provoked
1115 * by this method fails.
1116 * @see Field#set
1117 */
1118 @CallerSensitive
1119 @ForceInline // to ensure Reflection.getCallerClass optimization
1120 public void setInt(Object obj, int i)
1121 throws IllegalArgumentException, IllegalAccessException
1122 {
1123 if (!override) {
1124 Class<?> caller = Reflection.getCallerClass();
1125 checkAccess(caller, obj);
1126 getFieldAccessor().setInt(obj, i);
1127 return;
1128 }
1129
1130 FieldAccessor fa = getOverrideFieldAccessor();
1131 if (!Modifier.isFinal(modifiers)) {
1132 fa.setInt(obj, i);
1133 } else {
1134 setFinal(Reflection.getCallerClass(), obj, () -> fa.setInt(obj, i));
1135 }
1136 }
1137
1138 /**
1139 * Sets the value of a field as a {@code long} on the specified object.
1140 * This method is equivalent to
1141 * {@code set(obj, lObj)},
1142 * where {@code lObj} is a {@code Long} object and
1143 * {@code lObj.longValue() == l}.
1144 *
1145 * @param obj the object whose field should be modified
1146 * @param l the new value for the field of {@code obj}
1147 * being modified
1148 *
1149 * @throws IllegalAccessException if this {@code Field} object
1150 * is enforcing Java language access control and the underlying
1151 * field is either inaccessible or final;
1152 * or if this {@code Field} object has no write access.
1153 * @throws IllegalArgumentException if the specified object is not an
1154 * instance of the class or interface declaring the underlying
1155 * field (or a subclass or implementor thereof),
1156 * or if an unwrapping conversion fails.
1157 * @throws NullPointerException if the specified object is null
1158 * and the field is an instance field.
1159 * @throws ExceptionInInitializerError if the initialization provoked
1160 * by this method fails.
1161 * @see Field#set
1162 */
1163 @CallerSensitive
1164 @ForceInline // to ensure Reflection.getCallerClass optimization
1165 public void setLong(Object obj, long l)
1166 throws IllegalArgumentException, IllegalAccessException
1167 {
1168 if (!override) {
1169 Class<?> caller = Reflection.getCallerClass();
1170 checkAccess(caller, obj);
1171 getFieldAccessor().setLong(obj, l);
1172 return;
1173 }
1174
1175 FieldAccessor fa = getOverrideFieldAccessor();
1176 if (!Modifier.isFinal(modifiers)) {
1177 fa.setLong(obj, l);
1178 } else {
1179 setFinal(Reflection.getCallerClass(), obj, () -> fa.setLong(obj, l));
1180 }
1181 }
1182
1183 /**
1184 * Sets the value of a field as a {@code float} on the specified object.
1185 * This method is equivalent to
1186 * {@code set(obj, fObj)},
1187 * where {@code fObj} is a {@code Float} object and
1188 * {@code fObj.floatValue() == f}.
1189 *
1190 * @param obj the object whose field should be modified
1191 * @param f the new value for the field of {@code obj}
1192 * being modified
1193 *
1194 * @throws IllegalAccessException if this {@code Field} object
1195 * is enforcing Java language access control and the underlying
1196 * field is either inaccessible or final;
1197 * or if this {@code Field} object has no write access.
1198 * @throws IllegalArgumentException if the specified object is not an
1199 * instance of the class or interface declaring the underlying
1200 * field (or a subclass or implementor thereof),
1201 * or if an unwrapping conversion fails.
1202 * @throws NullPointerException if the specified object is null
1203 * and the field is an instance field.
1204 * @throws ExceptionInInitializerError if the initialization provoked
1205 * by this method fails.
1206 * @see Field#set
1207 */
1208 @CallerSensitive
1209 @ForceInline // to ensure Reflection.getCallerClass optimization
1210 public void setFloat(Object obj, float f)
1211 throws IllegalArgumentException, IllegalAccessException
1212 {
1213 if (!override) {
1214 Class<?> caller = Reflection.getCallerClass();
1215 checkAccess(caller, obj);
1216 getFieldAccessor().setFloat(obj, f);
1217 return;
1218 }
1219
1220 FieldAccessor fa = getOverrideFieldAccessor();
1221 if (!Modifier.isFinal(modifiers)) {
1222 fa.setFloat(obj, f);
1223 } else {
1224 setFinal(Reflection.getCallerClass(), obj, () -> fa.setFloat(obj, f));
1225 }
1226 }
1227
1228 /**
1229 * Sets the value of a field as a {@code double} on the specified object.
1230 * This method is equivalent to
1231 * {@code set(obj, dObj)},
1232 * where {@code dObj} is a {@code Double} object and
1233 * {@code dObj.doubleValue() == d}.
1234 *
1235 * @param obj the object whose field should be modified
1236 * @param d the new value for the field of {@code obj}
1237 * being modified
1238 *
1239 * @throws IllegalAccessException if this {@code Field} object
1240 * is enforcing Java language access control and the underlying
1241 * field is either inaccessible or final;
1242 * or if this {@code Field} object has no write access.
1243 * @throws IllegalArgumentException if the specified object is not an
1244 * instance of the class or interface declaring the underlying
1245 * field (or a subclass or implementor thereof),
1246 * or if an unwrapping conversion fails.
1247 * @throws NullPointerException if the specified object is null
1248 * and the field is an instance field.
1249 * @throws ExceptionInInitializerError if the initialization provoked
1250 * by this method fails.
1251 * @see Field#set
1252 */
1253 @CallerSensitive
1254 @ForceInline // to ensure Reflection.getCallerClass optimization
1255 public void setDouble(Object obj, double d)
1256 throws IllegalArgumentException, IllegalAccessException
1257 {
1258 if (!override) {
1259 Class<?> caller = Reflection.getCallerClass();
1260 checkAccess(caller, obj);
1261 getFieldAccessor().setDouble(obj, d);
1262 return;
1263 }
1264
1265 FieldAccessor fa = getOverrideFieldAccessor();
1266 if (!Modifier.isFinal(modifiers)) {
1267 fa.setDouble(obj, d);
1268 } else {
1269 setFinal(Reflection.getCallerClass(), obj, () -> fa.setDouble(obj, d));
1270 }
1271 }
1272
1273 // check access to field
1274 private void checkAccess(Class<?> caller, Object obj)
1275 throws IllegalAccessException
1276 {
1277 checkAccess(caller, clazz,
1278 Modifier.isStatic(modifiers) ? null : obj.getClass(),
1279 modifiers);
1280 }
1281
1282 private FieldAccessor getFieldAccessor() {
1283 FieldAccessor a = fieldAccessor;
1284 return (a != null) ? a : acquireFieldAccessor();
1285 }
1286
1287 private FieldAccessor getOverrideFieldAccessor() {
1288 FieldAccessor a = overrideFieldAccessor;
1289 return (a != null) ? a : acquireOverrideFieldAccessor();
1290 }
1291
1292 // NOTE that there is no synchronization used here. It is correct
1293 // (though not efficient) to generate more than one FieldAccessor
1294 // for a given Field. However, avoiding synchronization will
1295 // probably make the implementation more scalable.
1296 private FieldAccessor acquireFieldAccessor() {
1297 // First check to see if one has been created yet, and take it
1298 // if so
1299 Field root = this.root;
1300 FieldAccessor tmp = root == null ? null : root.fieldAccessor;
1301 if (tmp != null) {
1302 fieldAccessor = tmp;
1303 } else {
1304 // Otherwise fabricate one and propagate it up to the root
1305 tmp = reflectionFactory.newFieldAccessor(this, false);
1306 setFieldAccessor(tmp);
1307 }
1308 return tmp;
1309 }
1310
1311 private FieldAccessor acquireOverrideFieldAccessor() {
1312 // First check to see if one has been created yet, and take it
1313 // if so
1314 Field root = this.root;
1315 FieldAccessor tmp = root == null ? null : root.overrideFieldAccessor;
1316 if (tmp != null) {
1317 overrideFieldAccessor = tmp;
1318 } else {
1319 // Otherwise fabricate one and propagate it up to the root
1320 tmp = reflectionFactory.newFieldAccessor(this, true);
1321 setOverrideFieldAccessor(tmp);
1322 }
1323 return tmp;
1324 }
1325
1326 // Sets the fieldAccessor for this Field object and
1327 // (recursively) its root
1328 private void setFieldAccessor(FieldAccessor accessor) {
1329 fieldAccessor = accessor;
1330 // Propagate up
1331 Field root = this.root;
1332 if (root != null) {
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 */
1375 @Override
1376 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
1377 Objects.requireNonNull(annotationClass);
1378
1379 return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
1380 }
1381
1382 /**
1383 * {@inheritDoc}
1384 */
1385 @Override
1386 public Annotation[] getDeclaredAnnotations() {
1387 return AnnotationParser.toArray(declaredAnnotations());
1388 }
1389
1390 private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
1391
1392 private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
1393 Map<Class<? extends Annotation>, Annotation> declAnnos;
1394 if ((declAnnos = declaredAnnotations) == null) {
1395 synchronized (this) {
1396 if ((declAnnos = declaredAnnotations) == null) {
1397 Field root = this.root;
1398 if (root != null) {
1399 declAnnos = root.declaredAnnotations();
1400 } else {
1401 declAnnos = AnnotationParser.parseAnnotations(
1402 annotations,
1403 SharedSecrets.getJavaLangAccess()
1404 .getConstantPool(getDeclaringClass()),
1405 getDeclaringClass());
1406 }
1407 declaredAnnotations = declAnnos;
1408 }
1409 }
1410 }
1411 return declAnnos;
1412 }
1413
1414 private native byte[] getTypeAnnotationBytes0();
1415
1416 /**
1417 * Returns an AnnotatedType object that represents the use of a type to specify
1418 * the declared type of the field represented by this Field.
1419 * @return an object representing the declared type of the field
1420 * represented by this Field
1421 *
1422 * @since 1.8
1423 */
1424 public AnnotatedType getAnnotatedType() {
1425 return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
1426 SharedSecrets.getJavaLangAccess().
1427 getConstantPool(getDeclaringClass()),
1428 this,
1429 getDeclaringClass(),
1430 getGenericType(),
1431 TypeAnnotation.TypeAnnotationTarget.FIELD);
1432 }
1433
1434 /**
1435 * A function that sets a field to a value.
1436 */
1437 @FunctionalInterface
1438 private interface FieldSetter {
1439 void setFieldValue() throws IllegalAccessException;
1440 }
1441
1442 /**
1443 * Attempts to set a final field.
1444 */
1445 private void setFinal(Class<?> caller, Object obj, FieldSetter setter) throws IllegalAccessException {
1446 if (obj != null && isFinalInstanceInNormalClass()) {
1447 preSetFinal(caller, false);
1448 setter.setFieldValue();
1449 postSetFinal(caller, false);
1450 } else {
1451 // throws IllegalAccessException if static, or field in record or hidden class
1452 setter.setFieldValue();
1453 }
1454 }
1455
1456 /**
1457 * Return true if this field is a final instance field in a normal class (not a
1458 * record class or hidden class),
1459 */
1460 private boolean isFinalInstanceInNormalClass() {
1461 return Modifier.isFinal(modifiers)
1462 && !Modifier.isStatic(modifiers)
1463 && !clazz.isRecord()
1464 && !clazz.isHidden();
1465 }
1466
1467 /**
1468 * Check that the caller is allowed to unreflect for mutation a final instance field
1469 * in a normal class.
1470 * @throws IllegalAccessException if not allowed
1471 */
1472 void checkAllowedToUnreflectFinalSetter(Class<?> caller) throws IllegalAccessException {
1473 Objects.requireNonNull(caller);
1474 preSetFinal(caller, true);
1475 postSetFinal(caller, true);
1476 }
1477
1478 /**
1479 * Invoke before attempting to mutate, or unreflect for mutation, a final instance
1480 * field in a normal class.
1481 * @throws IllegalAccessException if not allowed
1482 */
1483 private void preSetFinal(Class<?> caller, boolean unreflect) throws IllegalAccessException {
1484 assert isFinalInstanceInNormalClass();
1485
1486 if (caller != null) {
1487 // check if declaring class in package that is open to caller, or public field
1488 // and declaring class is public in package exported to caller
1489 if (!isFinalDeeplyAccessible(caller)) {
1490 throw new IllegalAccessException(notAccessibleToCallerMessage(caller, unreflect));
1491 }
1492 } else {
1493 // no java caller, only allowed if field is public in exported package
1494 if (!Reflection.verifyPublicMemberAccess(clazz, modifiers)) {
1495 throw new IllegalAccessException(notAccessibleToNoCallerMessage(unreflect));
1496 }
1497 }
1498
1499 // check if field mutation is enabled for caller module or illegal final field
1500 // mutation is allowed
1501 var mode = ModuleBootstrap.illegalFinalFieldMutation();
1502 if (mode == ModuleBootstrap.IllegalFinalFieldMutation.DENY
1503 && !Modules.isFinalMutationEnabled(moduleToCheck(caller))) {
1504 throw new IllegalAccessException(callerNotAllowedToMutateMessage(caller, unreflect));
1505 }
1506 }
1507
1508 /**
1509 * Invoke after mutating a final instance field, or when unreflecting a final instance
1510 * field for mutation, to print a warning and record a JFR event.
1511 */
1512 private void postSetFinal(Class<?> caller, boolean unreflect) {
1513 assert isFinalInstanceInNormalClass();
1514
1515 var mode = ModuleBootstrap.illegalFinalFieldMutation();
1516 if (mode == ModuleBootstrap.IllegalFinalFieldMutation.WARN) {
1517 // first mutation prints warning
1518 Module moduleToCheck = moduleToCheck(caller);
1519 if (Modules.tryEnableFinalMutation(moduleToCheck)) {
1520 String warningMsg = finalFieldMutationWarning(caller, unreflect);
1521 String targetModule = (caller != null && moduleToCheck.isNamed())
1522 ? moduleToCheck.getName()
1523 : "ALL-UNNAMED";
1524 VM.initialErr().printf("""
1525 WARNING: %s
1526 WARNING: Use --enable-final-field-mutation=%s to avoid a warning
1527 WARNING: Mutating final fields will be blocked in a future release unless final field mutation is enabled
1528 """, warningMsg, targetModule);
1529 }
1530 } else if (mode == ModuleBootstrap.IllegalFinalFieldMutation.DEBUG) {
1531 // print warning and stack trace
1532 var sb = new StringBuilder(finalFieldMutationWarning(caller, unreflect));
1533 StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
1534 .forEach(sf -> {
1535 sb.append(System.lineSeparator()).append("\tat " + sf);
1536 });
1537 VM.initialErr().println(sb);
1538 }
1539
1540 // record JFR event
1541 FinalFieldMutationEvent.offer(getDeclaringClass(), getName());
1542 }
1543
1544 /**
1545 * Returns true if this final field is "deeply accessible" to the caller.
1546 * The field is deeply accessible if declaring class is in a package that is open
1547 * to the caller's module, or the field is public in a public class that is exported
1548 * to the caller's module.
1549 *
1550 * Updates to the module of the declaring class at runtime with {@code Module.addExports}
1551 * or {@code Module.addOpens} have no impact on the result of this method.
1552 */
1553 private boolean isFinalDeeplyAccessible(Class<?> caller) {
1554 assert isFinalInstanceInNormalClass();
1555
1556 // all fields in unnamed modules are deeply accessible
1557 Module declaringModule = clazz.getModule();
1558 if (!declaringModule.isNamed()) return true;
1559
1560 // all fields in the caller's module are deeply accessible
1561 Module callerModule = caller.getModule();
1562 if (callerModule == declaringModule) return true;
1563
1564 // public field, public class, package exported to caller's module
1565 String pn = clazz.getPackageName();
1566 if (Modifier.isPublic(modifiers)
1567 && Modifier.isPublic(clazz.getModifiers())
1568 && Modules.isStaticallyExported(declaringModule, pn, callerModule)) {
1569 return true;
1570 }
1571
1572 // package open to caller's module
1573 return Modules.isStaticallyOpened(declaringModule, pn, callerModule);
1574 }
1575
1576 /**
1577 * Returns the Module to use for access checks with the given caller.
1578 */
1579 private Module moduleToCheck(Class<?> caller) {
1580 if (caller != null) {
1581 return caller.getModule();
1582 } else {
1583 // no java caller, only allowed if field is public in exported package
1584 return ClassLoaders.appClassLoader().getUnnamedModule();
1585 }
1586 }
1587
1588 /**
1589 * Returns the warning message to print when this final field is mutated by
1590 * the given possibly-null caller.
1591 */
1592 private String finalFieldMutationWarning(Class<?> caller, boolean unreflect) {
1593 assert Modifier.isFinal(modifiers);
1594 String source;
1595 if (caller != null) {
1596 source = caller + " in " + caller.getModule();
1597 CodeSource cs = caller.getProtectionDomain().getCodeSource();
1598 if (cs != null) {
1599 URL url = cs.getLocation();
1600 if (url != null) {
1601 source += " (" + url + ")";
1602 }
1603 }
1604 } else {
1605 source = "JNI attached thread with no caller frame";
1606 }
1607 return String.format("Final field %s in %s has been %s by %s",
1608 name,
1609 clazz,
1610 (unreflect) ? "unreflected for mutation" : "mutated reflectively",
1611 source);
1612 }
1613
1614 /**
1615 * Returns the message for an IllegalAccessException when a final field cannot be
1616 * mutated because the declaring class is in a package that is not "deeply accessible"
1617 * to the caller.
1618 */
1619 private String notAccessibleToCallerMessage(Class<?> caller, boolean unreflect) {
1620 String exportsOrOpens = Modifier.isPublic(modifiers)
1621 && Modifier.isPublic(clazz.getModifiers()) ? "exports" : "opens";
1622 return String.format("%s, %s does not explicitly \"%s\" package %s to %s",
1623 cannotSetFieldMessage(caller, unreflect),
1624 clazz.getModule(),
1625 exportsOrOpens,
1626 clazz.getPackageName(),
1627 caller.getModule());
1628 }
1629
1630 /**
1631 * Returns the exception message for the IllegalAccessException when this
1632 * final field cannot be mutated because the caller module is not allowed
1633 * to mutate final fields.
1634 */
1635 private String callerNotAllowedToMutateMessage(Class<?> caller, boolean unreflect) {
1636 if (caller != null) {
1637 return String.format("%s, %s is not allowed to mutate final fields",
1638 cannotSetFieldMessage(caller, unreflect),
1639 caller.getModule());
1640 } else {
1641 return notAccessibleToNoCallerMessage(unreflect);
1642 }
1643 }
1644
1645 /**
1646 * Returns the message for an IllegalAccessException when a field is not
1647 * accessible to a JNI attached thread.
1648 */
1649 private String notAccessibleToNoCallerMessage(boolean unreflect) {
1650 return cannotSetFieldMessage("JNI attached thread with no caller frame cannot", unreflect);
1651 }
1652
1653 /**
1654 * Returns a message to indicate that the caller cannot set/unreflect this final field.
1655 */
1656 private String cannotSetFieldMessage(Class<?> caller, boolean unreflect) {
1657 return cannotSetFieldMessage(caller + " (in " + caller.getModule() + ") cannot", unreflect);
1658 }
1659
1660 /**
1661 * Returns a message to indicate that a field cannot be set/unreflected.
1662 */
1663 private String cannotSetFieldMessage(String prefix, boolean unreflect) {
1664 if (unreflect) {
1665 return prefix + " unreflect final field " + clazz.getName() + "." + name
1666 + " (in " + clazz.getModule() + ") for mutation";
1667 } else {
1668 return prefix + " set final field " + clazz.getName() + "." + name
1669 + " (in " + clazz.getModule() + ")";
1670 }
1671 }
1672 }