1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.lang3.reflect;
18
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.AccessibleObject;
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Modifier;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Objects;
27 import java.util.stream.Collectors;
28
29 import org.apache.commons.lang3.ArrayUtils;
30 import org.apache.commons.lang3.ClassUtils;
31 import org.apache.commons.lang3.JavaVersion;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.commons.lang3.SystemUtils;
34 import org.apache.commons.lang3.Validate;
35
36 /**
37 * Utilities for working with {@link Field}s by reflection. Adapted and refactored from the dormant [reflect] Commons
38 * sandbox component.
39 * <p>
40 * The ability is provided to break the scoping restrictions coded by the programmer. This can allow fields to be
41 * changed that shouldn't be. This facility should be used with care.
42 * </p>
43 *
44 * @since 2.5
45 */
46 public class FieldUtils {
47
48 /**
49 * Gets all fields of the given class and its parents (if any).
50 *
51 * @param cls
52 * the {@link Class} to query
53 * @return an array of Fields (possibly empty).
54 * @throws NullPointerException
55 * if the class is {@code null}.
56 * @since 3.2
57 */
58 public static Field[] getAllFields(final Class<?> cls) {
59 return getAllFieldsList(cls).toArray(ArrayUtils.EMPTY_FIELD_ARRAY);
60 }
61
62 /**
63 * Gets all fields of the given class and its parents (if any).
64 *
65 * @param cls
66 * the {@link Class} to query
67 * @return a list of Fields (possibly empty).
68 * @throws NullPointerException
69 * if the class is {@code null}.
70 * @since 3.2
71 */
72 public static List<Field> getAllFieldsList(final Class<?> cls) {
73 Objects.requireNonNull(cls, "cls");
74 final List<Field> allFields = new ArrayList<>();
75 Class<?> currentClass = cls;
76 while (currentClass != null) {
77 Collections.addAll(allFields, currentClass.getDeclaredFields());
78 currentClass = currentClass.getSuperclass();
79 }
80 return allFields;
81 }
82
83 /**
84 * Gets an accessible {@link Field} by name respecting scope. Only the specified class will be considered.
85 *
86 * @param cls
87 * the {@link Class} to reflect, must not be {@code null}
88 * @param fieldName
89 * the field name to obtain.
90 * @return the Field object.
91 * @throws NullPointerException
92 * if the class is {@code null}.
93 * @throws IllegalArgumentException
94 * if the field name is {@code null}, blank, or empty.
95 * @throws SecurityException if an underlying accessible object's method denies the request.
96 * @see SecurityManager#checkPermission
97 */
98 public static Field getDeclaredField(final Class<?> cls, final String fieldName) {
99 return getDeclaredField(cls, fieldName, false);
100 }
101
102 /**
103 * Gets an accessible {@link Field} by name, breaking scope if requested. Only the specified class will be
104 * considered.
105 *
106 * @param cls
107 * the {@link Class} to reflect, must not be {@code null}.
108 * @param fieldName
109 * the field name to obtain.
110 * @param forceAccess
111 * whether to break scope restrictions using the
112 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
113 * match {@code public} fields.
114 * @return the Field object
115 * @throws NullPointerException
116 * if the class is {@code null}.
117 * @throws IllegalArgumentException
118 * if the field name is {@code null}, blank, or empty.
119 * @throws SecurityException if an underlying accessible object's method denies the request.
120 * @see SecurityManager#checkPermission
121 */
122 public static Field getDeclaredField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
123 Objects.requireNonNull(cls, "cls");
124 Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty");
125 try {
126 // only consider the specified class by using getDeclaredField()
127 final Field field = cls.getDeclaredField(fieldName);
128 if (!MemberUtils.isAccessible(field)) {
129 if (!forceAccess) {
130 return null;
131 }
132 field.setAccessible(true);
133 }
134 return field;
135 } catch (final NoSuchFieldException ignored) {
136 // ignore
137 }
138 return null;
139 }
140
141 /**
142 * Gets an accessible {@link Field} by name respecting scope. Superclasses/interfaces will be considered.
143 *
144 * @param cls
145 * the {@link Class} to reflect, must not be {@code null}.
146 * @param fieldName
147 * the field name to obtain.
148 * @return the Field object.
149 * @throws NullPointerException
150 * if the class is {@code null}.
151 * @throws IllegalArgumentException
152 * if the field name is {@code null}, blank, or empty
153 * @throws SecurityException if an underlying accessible object's method denies the request.
154 * @see SecurityManager#checkPermission
155 */
156 public static Field getField(final Class<?> cls, final String fieldName) {
157 return MemberUtils.setAccessibleWorkaround(getField(cls, fieldName, false));
158 }
159
160 /**
161 * Gets an accessible {@link Field} by name, breaking scope if requested. Superclasses/interfaces will be
162 * considered.
163 *
164 * @param cls
165 * the {@link Class} to reflect, must not be {@code null}.
166 * @param fieldName
167 * the field name to obtain.
168 * @param forceAccess
169 * whether to break scope restrictions using the
170 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
171 * match {@code public} fields.
172 * @return the Field object.
173 * @throws NullPointerException if the class is {@code null}.
174 * @throws IllegalArgumentException if the field name is blank or empty or is matched at multiple places
175 * in the inheritance hierarchy.
176 * @throws SecurityException if an underlying accessible object's method denies the request.
177 * @see SecurityManager#checkPermission
178 */
179 public static Field getField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
180 Objects.requireNonNull(cls, "cls");
181 Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty");
182 // FIXME is this workaround still needed? lang requires Java 6
183 // Sun Java 1.3 has a bugged implementation of getField hence we write the
184 // code ourselves
185
186 // getField() will return the Field object with the declaring class
187 // set correctly to the class that declares the field. Thus requesting the
188 // field on a subclass will return the field from the superclass.
189 //
190 // priority order for lookup:
191 // searchclass private/protected/package/public
192 // superclass protected/package/public
193 // private/different package blocks access to further superclasses
194 // implementedinterface public
195
196 // check up the superclass hierarchy
197 for (Class<?> acls = cls; acls != null; acls = acls.getSuperclass()) {
198 try {
199 final Field field = acls.getDeclaredField(fieldName);
200 // getDeclaredField checks for non-public scopes as well
201 // and it returns accurate results
202 if (!MemberUtils.isPublic(field)) {
203 if (!forceAccess) {
204 continue;
205 }
206 field.setAccessible(true);
207 }
208 return field;
209 } catch (final NoSuchFieldException ignored) {
210 // ignore
211 }
212 }
213 // check the public interface case. This must be manually searched for
214 // incase there is a public supersuperclass field hidden by a private/package
215 // superclass field.
216 Field match = null;
217 for (final Class<?> class1 : ClassUtils.getAllInterfaces(cls)) {
218 try {
219 final Field test = class1.getField(fieldName);
220 Validate.isTrue(match == null,
221 "Reference to field %s is ambiguous relative to %s; a matching field exists on two or more implemented interfaces.", fieldName, cls);
222 match = test;
223 } catch (final NoSuchFieldException ignored) {
224 // ignore
225 }
226 }
227 return match;
228 }
229
230 /**
231 * Gets all fields of the given class and its parents (if any) that are annotated with the given annotation.
232 *
233 * @param cls
234 * the {@link Class} to query.
235 * @param annotationCls
236 * the {@link Annotation} that must be present on a field to be matched.
237 * @return a list of Fields (possibly empty).
238 * @throws NullPointerException
239 * if the class or annotation are {@code null}.
240 * @since 3.4
241 */
242 public static List<Field> getFieldsListWithAnnotation(final Class<?> cls, final Class<? extends Annotation> annotationCls) {
243 Objects.requireNonNull(annotationCls, "annotationCls");
244 return getAllFieldsList(cls).stream().filter(field -> field.getAnnotation(annotationCls) != null).collect(Collectors.toList());
245 }
246
247 /**
248 * Gets all fields of the given class and its parents (if any) that are annotated with the given annotation.
249 *
250 * @param cls
251 * the {@link Class} to query.
252 * @param annotationCls
253 * the {@link Annotation} that must be present on a field to be matched
254 * @return an array of Fields (possibly empty).
255 * @throws NullPointerException
256 * if the class or annotation are {@code null}.
257 * @since 3.4
258 */
259 public static Field[] getFieldsWithAnnotation(final Class<?> cls, final Class<? extends Annotation> annotationCls) {
260 return getFieldsListWithAnnotation(cls, annotationCls).toArray(ArrayUtils.EMPTY_FIELD_ARRAY);
261 }
262
263 /**
264 * Reads the named {@code public} {@link Field}. Only the class of the specified object will be considered.
265 *
266 * @param target
267 * the object to reflect, must not be {@code null}.
268 * @param fieldName
269 * the field name to obtain.
270 * @return the value of the field.
271 * @throws NullPointerException
272 * if {@code target} is {@code null}.
273 * @throws IllegalArgumentException
274 * if {@code fieldName} is {@code null}, blank or empty, or could not be found.
275 * @throws IllegalAccessException
276 * if the named field is not {@code public}
277 * @throws SecurityException if an underlying accessible object's method denies the request.
278 * @see SecurityManager#checkPermission
279 */
280 public static Object readDeclaredField(final Object target, final String fieldName) throws IllegalAccessException {
281 return readDeclaredField(target, fieldName, false);
282 }
283
284 /**
285 * Gets a {@link Field} value by name. Only the class of the specified object will be considered.
286 *
287 * @param target
288 * the object to reflect, must not be {@code null}.
289 * @param fieldName
290 * the field name to obtain.
291 * @param forceAccess
292 * whether to break scope restrictions using the
293 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
294 * match public fields.
295 * @return the Field object.
296 * @throws NullPointerException
297 * if {@code target} is {@code null}.
298 * @throws IllegalArgumentException
299 * if {@code fieldName} is {@code null}, blank or empty, or could not be found.
300 * @throws IllegalAccessException
301 * if the field is not made accessible.
302 * @throws SecurityException if an underlying accessible object's method denies the request.
303 * @see SecurityManager#checkPermission
304 */
305 public static Object readDeclaredField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
306 Objects.requireNonNull(target, "target");
307 final Class<?> cls = target.getClass();
308 final Field field = getDeclaredField(cls, fieldName, forceAccess);
309 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls, fieldName);
310 // already forced access above, don't repeat it here:
311 return readField(field, target, false);
312 }
313
314 /**
315 * Gets the value of a {@code static} {@link Field} by name. The field must be {@code public}. Only the specified
316 * class will be considered.
317 *
318 * @param cls
319 * the {@link Class} to reflect, must not be {@code null}.
320 * @param fieldName
321 * the field name to obtain.
322 * @return the value of the field.
323 * @throws NullPointerException
324 * if the class is {@code null}, or the field could not be found.
325 * @throws IllegalArgumentException
326 * if the field name is {@code null}, blank, empty, or is not {@code static}.
327 * @throws IllegalAccessException
328 * if the field is not accessible
329 * @throws SecurityException if an underlying accessible object's method denies the request.
330 * @see SecurityManager#checkPermission
331 */
332 public static Object readDeclaredStaticField(final Class<?> cls, final String fieldName) throws IllegalAccessException {
333 return readDeclaredStaticField(cls, fieldName, false);
334 }
335
336 /**
337 * Gets the value of a {@code static} {@link Field} by name. Only the specified class will be considered.
338 *
339 * @param cls
340 * the {@link Class} to reflect, must not be {@code null}.
341 * @param fieldName
342 * the field name to obtain.
343 * @param forceAccess
344 * whether to break scope restrictions using the
345 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
346 * match {@code public} fields.
347 * @return the Field object
348 * @throws NullPointerException
349 * if the class is {@code null}, or the field could not be found.
350 * @throws IllegalArgumentException
351 * if the field name is blank or empty, is not {@code static}.
352 * @throws IllegalAccessException
353 * if the field is not made accessible
354 * @throws SecurityException if an underlying accessible object's method denies the request.
355 * @see SecurityManager#checkPermission
356 */
357 public static Object readDeclaredStaticField(final Class<?> cls, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
358 final Field field = getDeclaredField(cls, fieldName, forceAccess);
359 Validate.notNull(field, "Cannot locate declared field %s.%s", cls.getName(), fieldName);
360 // already forced access above, don't repeat it here:
361 return readStaticField(field, false);
362 }
363
364 /**
365 * Reads an accessible {@link Field}.
366 *
367 * @param field
368 * the field to use.
369 * @param target
370 * the object to call on, may be {@code null} for {@code static} fields.
371 * @return the field value
372 * @throws NullPointerException
373 * if the field is {@code null}.
374 * @throws IllegalAccessException
375 * if the field is not accessible.
376 * @throws SecurityException if an underlying accessible object's method denies the request.
377 * @see SecurityManager#checkPermission
378 */
379 public static Object readField(final Field field, final Object target) throws IllegalAccessException {
380 return readField(field, target, false);
381 }
382
383 /**
384 * Reads a {@link Field}.
385 *
386 * @param field
387 * the field to use.
388 * @param target
389 * the object to call on, may be {@code null} for {@code static} fields.
390 * @param forceAccess
391 * whether to break scope restrictions using the
392 * {@link AccessibleObject#setAccessible(boolean)} method.
393 * @return the field value
394 * @throws NullPointerException
395 * if the field is {@code null}.
396 * @throws IllegalAccessException
397 * if the field is not made accessible.
398 * @throws SecurityException if an underlying accessible object's method denies the request.
399 * @see SecurityManager#checkPermission
400 * @throws SecurityException if an underlying accessible object's method denies the request.
401 * @see SecurityManager#checkPermission
402 */
403 public static Object readField(final Field field, final Object target, final boolean forceAccess) throws IllegalAccessException {
404 Objects.requireNonNull(field, "field");
405 return setAccessible(field, forceAccess).get(target);
406 }
407
408 /**
409 * Reads the named {@code public} {@link Field}. Superclasses will be considered.
410 *
411 * @param target
412 * the object to reflect, must not be {@code null}.
413 * @param fieldName
414 * the field name to obtain.
415 * @return the value of the field.
416 * @throws NullPointerException
417 * if the target is {@code null}.
418 * @throws IllegalArgumentException
419 * if the field name is {@code null}, blank, empty, or could not be found.
420 * @throws IllegalAccessException
421 * if the named field is not {@code public}.
422 * @throws SecurityException if an underlying accessible object's method denies the request.
423 * @see SecurityManager#checkPermission
424 */
425 public static Object readField(final Object target, final String fieldName) throws IllegalAccessException {
426 return readField(target, fieldName, false);
427 }
428
429 /**
430 * Reads the named {@link Field}. Superclasses will be considered.
431 *
432 * @param target
433 * the object to reflect, must not be {@code null}.
434 * @param fieldName
435 * the field name to obtain.
436 * @param forceAccess
437 * whether to break scope restrictions using the
438 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
439 * match {@code public} fields.
440 * @return the field value
441 * @throws NullPointerException
442 * if {@code target} is {@code null}.
443 * @throws IllegalArgumentException
444 * if the field name is {@code null}, blank, empty, or could not be found.
445 * @throws IllegalAccessException
446 * if the named field is not made accessible.
447 * @throws SecurityException if an underlying accessible object's method denies the request.
448 * @see SecurityManager#checkPermission
449 */
450 public static Object readField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
451 Objects.requireNonNull(target, "target");
452 final Class<?> cls = target.getClass();
453 final Field field = getField(cls, fieldName, forceAccess);
454 Validate.isTrue(field != null, "Cannot locate field %s on %s", fieldName, cls);
455 // already forced access above, don't repeat it here:
456 return readField(field, target, false);
457 }
458
459 /**
460 * Reads the named {@code public static} {@link Field}. Superclasses will be considered.
461 *
462 * @param cls
463 * the {@link Class} to reflect, must not be {@code null}.
464 * @param fieldName
465 * the field name to obtain.
466 * @return the value of the field.
467 * @throws NullPointerException
468 * if the class is {@code null}, or the field could not be found.
469 * @throws IllegalArgumentException
470 * if the field name is {@code null}, blank or empty, or is not {@code static}.
471 * @throws IllegalAccessException
472 * if the field is not accessible.
473 * @throws SecurityException if an underlying accessible object's method denies the request.
474 * @see SecurityManager#checkPermission
475 */
476 public static Object readStaticField(final Class<?> cls, final String fieldName) throws IllegalAccessException {
477 return readStaticField(cls, fieldName, false);
478 }
479
480 /**
481 * Reads the named {@code static} {@link Field}. Superclasses will be considered.
482 *
483 * @param cls
484 * the {@link Class} to reflect, must not be {@code null}.
485 * @param fieldName
486 * the field name to obtain.
487 * @param forceAccess
488 * whether to break scope restrictions using the
489 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
490 * match {@code public} fields.
491 * @return the Field object.
492 * @throws NullPointerException
493 * if the class is {@code null}, or the field could not be found.
494 * @throws IllegalArgumentException
495 * if the field name is {@code null}, blank or empty, or is not {@code static}.
496 * @throws IllegalAccessException
497 * if the field is not made accessible.
498 * @throws SecurityException if an underlying accessible object's method denies the request.
499 * @see SecurityManager#checkPermission
500 */
501 public static Object readStaticField(final Class<?> cls, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
502 final Field field = getField(cls, fieldName, forceAccess);
503 Validate.notNull(field, "Cannot locate field '%s' on %s", fieldName, cls);
504 // already forced access above, don't repeat it here:
505 return readStaticField(field, false);
506 }
507
508 /**
509 * Reads an accessible {@code static} {@link Field}.
510 *
511 * @param field
512 * to read.
513 * @return the field value.
514 * @throws NullPointerException
515 * if the field is {@code null}.
516 * @throws IllegalArgumentException
517 * if the field is not {@code static}.
518 * @throws IllegalAccessException
519 * if the field is not accessible
520 * @throws SecurityException if an underlying accessible object's method denies the request.
521 * @see SecurityManager#checkPermission
522 */
523 public static Object readStaticField(final Field field) throws IllegalAccessException {
524 return readStaticField(field, false);
525 }
526
527 /**
528 * Reads a static {@link Field}.
529 *
530 * @param field
531 * to read.
532 * @param forceAccess
533 * whether to break scope restrictions using the
534 * {@link AccessibleObject#setAccessible(boolean)} method.
535 * @return the field value.
536 * @throws NullPointerException
537 * if the field is {@code null}.
538 * @throws IllegalArgumentException
539 * if the field is not {@code static}.
540 * @throws IllegalAccessException
541 * if the field is not made accessible.
542 * @throws SecurityException if an underlying accessible object's method denies the request.
543 * @see SecurityManager#checkPermission
544 */
545 public static Object readStaticField(final Field field, final boolean forceAccess) throws IllegalAccessException {
546 Objects.requireNonNull(field, "field");
547 Validate.isTrue(MemberUtils.isStatic(field), "The field '%s' is not static", field.getName());
548 return readField(field, (Object) null, forceAccess);
549 }
550
551 /**
552 * Removes the final modifier from a {@link Field}.
553 *
554 * @param field
555 * to remove the final modifier.
556 * @throws NullPointerException
557 * if the field is {@code null}.
558 * @throws SecurityException if an underlying accessible object's method denies the request.
559 * @see SecurityManager#checkPermission
560 * @since 3.2
561 */
562 public static void removeFinalModifier(final Field field) {
563 removeFinalModifier(field, true);
564 }
565
566 /**
567 * Removes the final modifier from a {@link Field}.
568 *
569 * @param field
570 * to remove the final modifier.
571 * @param forceAccess
572 * whether to break scope restrictions using the
573 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
574 * match {@code public} fields.
575 * @throws NullPointerException
576 * if the field is {@code null}.
577 * @throws SecurityException if an underlying accessible object's method denies the request.
578 * @see SecurityManager#checkPermission
579 * @since 3.3
580 * @deprecated As of Java 12, we can no longer drop the {@code final} modifier, thus
581 * rendering this method obsolete. The JDK discussion about this change can be found
582 * here: https://mail.openjdk.java.net/pipermail/core-libs-dev/2018-November/056486.html
583 */
584 @Deprecated
585 public static void removeFinalModifier(final Field field, final boolean forceAccess) {
586 Objects.requireNonNull(field, "field");
587 try {
588 if (Modifier.isFinal(field.getModifiers())) {
589 // Do all JREs implement Field with a private ivar called "modifiers"?
590 final Field modifiersField = Field.class.getDeclaredField("modifiers");
591 final boolean doForceAccess = forceAccess && !modifiersField.isAccessible();
592 if (doForceAccess) {
593 modifiersField.setAccessible(true);
594 }
595 try {
596 modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
597 } finally {
598 if (doForceAccess) {
599 modifiersField.setAccessible(false);
600 }
601 }
602 }
603 } catch (final NoSuchFieldException | IllegalAccessException e) {
604 if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_12)) {
605 throw new UnsupportedOperationException("In java 12+ final cannot be removed.", e);
606 }
607 // else no exception is thrown because we can modify final.
608 }
609 }
610
611 static Field setAccessible(final Field field, final boolean forceAccess) {
612 if (forceAccess && !field.isAccessible()) {
613 field.setAccessible(true);
614 } else {
615 MemberUtils.setAccessibleWorkaround(field);
616 }
617 return field;
618 }
619
620 /**
621 * Writes a {@code public} {@link Field}. Only the specified class will be considered.
622 *
623 * @param target
624 * the object to reflect, must not be {@code null}.
625 * @param fieldName
626 * the field name to obtain.
627 * @param value
628 * the new value.
629 * @throws NullPointerException
630 * if {@code target} is {@code null}.
631 * @throws IllegalArgumentException
632 * if {@code fieldName} is {@code null}, blank or empty, or could not be found,
633 * or {@code value} is not assignable.
634 * @throws IllegalAccessException
635 * if the field is not made accessible
636 * @throws SecurityException if an underlying accessible object's method denies the request.
637 * @see SecurityManager#checkPermission
638 */
639 public static void writeDeclaredField(final Object target, final String fieldName, final Object value) throws IllegalAccessException {
640 writeDeclaredField(target, fieldName, value, false);
641 }
642
643 /**
644 * Writes a {@code public} {@link Field}. Only the specified class will be considered.
645 *
646 * @param target
647 * the object to reflect, must not be {@code null}.
648 * @param fieldName
649 * the field name to obtain.
650 * @param value
651 * the new value.
652 * @param forceAccess
653 * whether to break scope restrictions using the
654 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
655 * match {@code public} fields.
656 * @throws IllegalArgumentException
657 * if {@code fieldName} is {@code null}, blank or empty, or could not be found,
658 * or {@code value} is not assignable
659 * @throws IllegalAccessException
660 * if the field is not made accessible
661 * @throws SecurityException if an underlying accessible object's method denies the request.
662 * @see SecurityManager#checkPermission
663 */
664 public static void writeDeclaredField(final Object target, final String fieldName, final Object value, final boolean forceAccess)
665 throws IllegalAccessException {
666 Objects.requireNonNull(target, "target");
667 final Class<?> cls = target.getClass();
668 final Field field = getDeclaredField(cls, fieldName, forceAccess);
669 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls.getName(), fieldName);
670 // already forced access above, don't repeat it here:
671 writeField(field, target, value, false);
672 }
673
674 /**
675 * Writes a named {@code public static} {@link Field}. Only the specified class will be considered.
676 *
677 * @param cls
678 * {@link Class} on which the field is to be found.
679 * @param fieldName
680 * to write.
681 * @param value
682 * the new value.
683 * @throws NullPointerException
684 * if {@code cls} is {@code null} or the field cannot be located.
685 * @throws IllegalArgumentException
686 * if the field name is {@code null}, blank, empty, not {@code static}, or {@code value} is not assignable.
687 * @throws IllegalAccessException
688 * if the field is not {@code public} or is {@code final}
689 * @throws SecurityException if an underlying accessible object's method denies the request.
690 * @see SecurityManager#checkPermission
691 */
692 public static void writeDeclaredStaticField(final Class<?> cls, final String fieldName, final Object value) throws IllegalAccessException {
693 writeDeclaredStaticField(cls, fieldName, value, false);
694 }
695
696 /**
697 * Writes a named {@code static} {@link Field}. Only the specified class will be considered.
698 *
699 * @param cls
700 * {@link Class} on which the field is to be found.
701 * @param fieldName
702 * to write
703 * @param value
704 * the new value.
705 * @param forceAccess
706 * whether to break scope restrictions using the {@code AccessibleObject#setAccessible(boolean)} method.
707 * {@code false} will only match {@code public} fields.
708 * @throws NullPointerException
709 * if {@code cls} is {@code null} or the field cannot be located.
710 * @throws IllegalArgumentException
711 * if the field name is {@code null}, blank, empty, not {@code static}, or {@code value} is not assignable.
712 * @throws IllegalAccessException
713 * if the field is not made accessible or is {@code final}
714 * @throws SecurityException if an underlying accessible object's method denies the request.
715 * @see SecurityManager#checkPermission
716 */
717 public static void writeDeclaredStaticField(final Class<?> cls, final String fieldName, final Object value, final boolean forceAccess)
718 throws IllegalAccessException {
719 final Field field = getDeclaredField(cls, fieldName, forceAccess);
720 Validate.notNull(field, "Cannot locate declared field %s.%s", cls.getName(), fieldName);
721 // already forced access above, don't repeat it here:
722 writeField(field, (Object) null, value, false);
723 }
724
725 /**
726 * Writes an accessible {@link Field}.
727 *
728 * @param field
729 * to write.
730 * @param target
731 * the object to call on, may be {@code null} for {@code static} fields.
732 * @param value
733 * the new value.
734 * @throws NullPointerException
735 * if the field is {@code null}.
736 * @throws IllegalArgumentException
737 * if {@code value} is not assignable.
738 * @throws IllegalAccessException
739 * if the field is not accessible or is {@code final}.
740 * @throws SecurityException if an underlying accessible object's method denies the request.
741 * @see SecurityManager#checkPermission
742 */
743 public static void writeField(final Field field, final Object target, final Object value) throws IllegalAccessException {
744 writeField(field, target, value, false);
745 }
746
747 /**
748 * Writes a {@link Field}.
749 *
750 * @param field
751 * to write.
752 * @param target
753 * the object to call on, may be {@code null} for {@code static} fields
754 * @param value
755 * the new value.
756 * @param forceAccess
757 * whether to break scope restrictions using the
758 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
759 * match {@code public} fields.
760 * @throws NullPointerException
761 * if the field is {@code null}.
762 * @throws IllegalArgumentException
763 * if {@code value} is not assignable.
764 * @throws IllegalAccessException
765 * if the field is not made accessible or is {@code final}
766 * @throws SecurityException if an underlying accessible object's method denies the request.
767 * @see SecurityManager#checkPermission
768 */
769 public static void writeField(final Field field, final Object target, final Object value, final boolean forceAccess)
770 throws IllegalAccessException {
771 Objects.requireNonNull(field, "field");
772 setAccessible(field, forceAccess).set(target, value);
773 }
774
775 /**
776 * Writes a {@code public} {@link Field}. Superclasses will be considered.
777 *
778 * @param target
779 * the object to reflect, must not be {@code null}.
780 * @param fieldName
781 * the field name to obtain.
782 * @param value
783 * the new value.
784 * @throws NullPointerException
785 * if {@code target} is {@code null}.
786 * @throws IllegalArgumentException
787 * if {@code fieldName} is {@code null}, blank, empty, or could not be found,
788 * or {@code value} is not assignable.
789 * @throws IllegalAccessException
790 * if the field is not accessible.
791 * @throws SecurityException if an underlying accessible object's method denies the request.
792 * @see SecurityManager#checkPermission
793 */
794 public static void writeField(final Object target, final String fieldName, final Object value) throws IllegalAccessException {
795 writeField(target, fieldName, value, false);
796 }
797
798 /**
799 * Writes a {@link Field}. Superclasses will be considered.
800 *
801 * @param target
802 * the object to reflect, must not be {@code null}.
803 * @param fieldName
804 * the field name to obtain.
805 * @param value
806 * the new value.
807 * @param forceAccess
808 * whether to break scope restrictions using the
809 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
810 * match {@code public} fields.
811 * @throws NullPointerException
812 * if {@code target} is {@code null}.
813 * @throws IllegalArgumentException
814 * if {@code fieldName} is {@code null}, blank, empty, or could not be found,
815 * or {@code value} is not assignable.
816 * @throws IllegalAccessException
817 * if the field is not made accessible.
818 * @throws SecurityException if an underlying accessible object's method denies the request.
819 * @see SecurityManager#checkPermission
820 */
821 public static void writeField(final Object target, final String fieldName, final Object value, final boolean forceAccess)
822 throws IllegalAccessException {
823 Objects.requireNonNull(target, "target");
824 final Class<?> cls = target.getClass();
825 final Field field = getField(cls, fieldName, forceAccess);
826 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls.getName(), fieldName);
827 // already forced access above, don't repeat it here:
828 writeField(field, target, value, false);
829 }
830
831 /**
832 * Writes a named {@code public static} {@link Field}. Superclasses will be considered.
833 *
834 * @param cls
835 * {@link Class} on which the field is to be found.
836 * @param fieldName
837 * to write.
838 * @param value
839 * the new value.
840 * @throws NullPointerException
841 * if {@code target} is {@code null}.
842 * @throws IllegalArgumentException
843 * if {@code fieldName} is {@code null}, blank or empty, the field cannot be located or is
844 * not {@code static}, or {@code value} is not assignable.
845 * @throws IllegalAccessException
846 * if the field is not {@code public} or is {@code final}
847 * @throws SecurityException if an underlying accessible object's method denies the request.
848 * @see SecurityManager#checkPermission
849 */
850 public static void writeStaticField(final Class<?> cls, final String fieldName, final Object value) throws IllegalAccessException {
851 writeStaticField(cls, fieldName, value, false);
852 }
853
854 /**
855 * Writes a named {@code static} {@link Field}. Superclasses will be considered.
856 *
857 * @param cls
858 * {@link Class} on which the field is to be found.
859 * @param fieldName
860 * to write.
861 * @param value
862 * the new value.
863 * @param forceAccess
864 * whether to break scope restrictions using the
865 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
866 * match {@code public} fields.
867 * @throws NullPointerException
868 * if {@code cls} is {@code null} or the field cannot be located.
869 * @throws IllegalArgumentException
870 * if {@code fieldName} is {@code null}, blank or empty, the field not {@code static}, or {@code value} is not assignable.
871 * @throws IllegalAccessException
872 * if the field is not made accessible or is {@code final}.
873 * @throws SecurityException if an underlying accessible object's method denies the request.
874 * @see SecurityManager#checkPermission
875 */
876 public static void writeStaticField(final Class<?> cls, final String fieldName, final Object value, final boolean forceAccess)
877 throws IllegalAccessException {
878 final Field field = getField(cls, fieldName, forceAccess);
879 Validate.notNull(field, "Cannot locate field %s on %s", fieldName, cls);
880 // already forced access above, don't repeat it here:
881 writeStaticField(field, value, false);
882 }
883
884 /**
885 * Writes a {@code public static} {@link Field}.
886 *
887 * @param field
888 * to write.
889 * @param value
890 * the new value.
891 * @throws NullPointerException
892 * if the field is {@code null}.
893 * @throws IllegalArgumentException
894 * if the field is not {@code static}, or {@code value} is not assignable.
895 * @throws IllegalAccessException
896 * if the field is not {@code public} or is {@code final}.
897 * @throws SecurityException if an underlying accessible object's method denies the request.
898 * @see SecurityManager#checkPermission
899 */
900 public static void writeStaticField(final Field field, final Object value) throws IllegalAccessException {
901 writeStaticField(field, value, false);
902 }
903
904 /**
905 * Writes a static {@link Field}.
906 *
907 * @param field
908 * to write.
909 * @param value
910 * the new value.
911 * @param forceAccess
912 * whether to break scope restrictions using the
913 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only
914 * match {@code public} fields.
915 * @throws NullPointerException
916 * if the field is {@code null}.
917 * @throws IllegalArgumentException
918 * if the field is not {@code static}, or {@code value} is not assignable.
919 * @throws IllegalAccessException
920 * if the field is not made accessible or is {@code final}
921 * @throws SecurityException if an underlying accessible object's method denies the request.
922 * @see SecurityManager#checkPermission
923 */
924 public static void writeStaticField(final Field field, final Object value, final boolean forceAccess) throws IllegalAccessException {
925 Objects.requireNonNull(field, "field");
926 Validate.isTrue(MemberUtils.isStatic(field), "The field %s.%s is not static", field.getDeclaringClass().getName(),
927 field.getName());
928 writeField(field, (Object) null, value, forceAccess);
929 }
930
931 /**
932 * {@link FieldUtils} instances should NOT be constructed in standard programming.
933 * <p>
934 * This constructor is {@code public} to permit tools that require a JavaBean instance to operate.
935 * </p>
936 *
937 * @deprecated TODO Make private in 4.0.
938 */
939 @Deprecated
940 public FieldUtils() {
941 // empty
942 }
943 }