View Javadoc
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 }