Coverage Report - org.apache.commons.lang3.reflect.FieldUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
FieldUtils
95%
124/130
90%
60/66
3.138
 
 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  
  *      http://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.reflect.Field;
 20  
 import java.lang.reflect.Modifier;
 21  
 
 22  
 import org.apache.commons.lang3.ClassUtils;
 23  
 
 24  
 /**
 25  
  * Utilities for working with fields by reflection. Adapted and refactored
 26  
  * from the dormant [reflect] Commons sandbox component.
 27  
  * <p>
 28  
  * The ability is provided to break the scoping restrictions coded by the
 29  
  * programmer. This can allow fields to be changed that shouldn't be. This
 30  
  * facility should be used with care.
 31  
  *
 32  
  * @since 2.5
 33  
  * @version $Id: FieldUtils.java 1436770 2013-01-22 07:09:45Z ggregory $
 34  
  */
 35  
 public class FieldUtils {
 36  
 
 37  
     /**
 38  
      * FieldUtils instances should NOT be constructed in standard programming.
 39  
      * <p>
 40  
      * This constructor is public to permit tools that require a JavaBean instance
 41  
      * to operate.
 42  
      */
 43  
     public FieldUtils() {
 44  1
         super();
 45  1
     }
 46  
 
 47  
     /**
 48  
      * Gets an accessible <code>Field</code> by name respecting scope.
 49  
      * Superclasses/interfaces will be considered.
 50  
      *
 51  
      * @param cls  the class to reflect, must not be null
 52  
      * @param fieldName  the field name to obtain
 53  
      * @return the Field object
 54  
      * @throws IllegalArgumentException if the class or field name is null
 55  
      */
 56  
     public static Field getField(final Class<?> cls, final String fieldName) {
 57  23
         final Field field = getField(cls, fieldName, false);
 58  20
         MemberUtils.setAccessibleWorkaround(field);
 59  20
         return field;
 60  
     }
 61  
 
 62  
     /**
 63  
      * Gets an accessible <code>Field</code> by name breaking scope
 64  
      * if requested. Superclasses/interfaces will be considered.
 65  
      *
 66  
      * @param cls  the class to reflect, must not be null
 67  
      * @param fieldName  the field name to obtain
 68  
      * @param forceAccess  whether to break scope restrictions using the
 69  
      *  <code>setAccessible</code> method. <code>False</code> will only
 70  
      *  match public fields.
 71  
      * @return the Field object
 72  
      * @throws IllegalArgumentException if the class or field name is null
 73  
      */
 74  
     public static Field getField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
 75  142
         if (cls == null) {
 76  4
             throw new IllegalArgumentException("The class must not be null");
 77  
         }
 78  138
         if (fieldName == null) {
 79  6
             throw new IllegalArgumentException("The field name must not be null");
 80  
         }
 81  
         // Sun Java 1.3 has a bugged implementation of getField hence we write the
 82  
         // code ourselves
 83  
 
 84  
         // getField() will return the Field object with the declaring class
 85  
         // set correctly to the class that declares the field. Thus requesting the
 86  
         // field on a subclass will return the field from the superclass.
 87  
         //
 88  
         // priority order for lookup:
 89  
         // searchclass private/protected/package/public
 90  
         // superclass protected/package/public
 91  
         //  private/different package blocks access to further superclasses
 92  
         // implementedinterface public
 93  
 
 94  
         // check up the superclass hierarchy
 95  279
         for (Class<?> acls = cls; acls != null; acls = acls.getSuperclass()) {
 96  
             try {
 97  241
                 final Field field = acls.getDeclaredField(fieldName);
 98  
                 // getDeclaredField checks for non-public scopes as well
 99  
                 // and it returns accurate results
 100  134
                 if (!Modifier.isPublic(field.getModifiers())) {
 101  76
                     if (forceAccess) {
 102  36
                         field.setAccessible(true);
 103  
                     } else {
 104  40
                         continue;
 105  
                     }
 106  
                 }
 107  94
                 return field;
 108  107
             } catch (final NoSuchFieldException ex) { // NOPMD
 109  
                 // ignore
 110  
             }
 111  
         }
 112  
         // check the public interface case. This must be manually searched for
 113  
         // incase there is a public supersuperclass field hidden by a private/package
 114  
         // superclass field.
 115  38
         Field match = null;
 116  38
         for (final Class<?> class1 : ClassUtils.getAllInterfaces(cls)) {
 117  
             try {
 118  31
                 final Field test = ((Class<?>) class1).getField(fieldName);
 119  13
                 if (match != null) {
 120  1
                     throw new IllegalArgumentException("Reference to field " + fieldName + " is ambiguous relative to " + cls
 121  
                             + "; a matching field exists on two or more implemented interfaces.");
 122  
                 }
 123  12
                 match = test;
 124  18
             } catch (final NoSuchFieldException ex) { // NOPMD
 125  
                 // ignore
 126  12
             }
 127  30
         }
 128  37
         return match;
 129  
     }
 130  
 
 131  
     /**
 132  
      * Gets an accessible <code>Field</code> by name respecting scope.
 133  
      * Only the specified class will be considered.
 134  
      *
 135  
      * @param cls  the class to reflect, must not be null
 136  
      * @param fieldName  the field name to obtain
 137  
      * @return the Field object
 138  
      * @throws IllegalArgumentException if the class or field name is null
 139  
      */
 140  
     public static Field getDeclaredField(final Class<?> cls, final String fieldName) {
 141  19
         return getDeclaredField(cls, fieldName, false);
 142  
     }
 143  
 
 144  
     /**
 145  
      * Gets an accessible <code>Field</code> by name breaking scope
 146  
      * if requested. Only the specified class will be considered.
 147  
      *
 148  
      * @param cls  the class to reflect, must not be null
 149  
      * @param fieldName  the field name to obtain
 150  
      * @param forceAccess  whether to break scope restrictions using the
 151  
      *  <code>setAccessible</code> method. False will only match public fields.
 152  
      * @return the Field object
 153  
      * @throws IllegalArgumentException if the class or field name is null
 154  
      */
 155  
     public static Field getDeclaredField(final Class<?> cls, final String fieldName, final boolean forceAccess) {
 156  127
         if (cls == null) {
 157  2
             throw new IllegalArgumentException("The class must not be null");
 158  
         }
 159  125
         if (fieldName == null) {
 160  4
             throw new IllegalArgumentException("The field name must not be null");
 161  
         }
 162  
         try {
 163  
             // only consider the specified class by using getDeclaredField()
 164  121
             final Field field = cls.getDeclaredField(fieldName);
 165  89
             if (!MemberUtils.isAccessible(field)) {
 166  50
                 if (forceAccess) {
 167  30
                     field.setAccessible(true);
 168  
                 } else {
 169  20
                     return null;
 170  
                 }
 171  
             }
 172  69
             return field;
 173  32
         } catch (final NoSuchFieldException e) { // NOPMD
 174  
             // ignore
 175  
         }
 176  32
         return null;
 177  
     }
 178  
 
 179  
     /**
 180  
      * Reads an accessible static Field.
 181  
      * @param field to read
 182  
      * @return the field value
 183  
      * @throws IllegalArgumentException if the field is null or not static
 184  
      * @throws IllegalAccessException if the field is not accessible
 185  
      */
 186  
     public static Object readStaticField(final Field field) throws IllegalAccessException {
 187  7
         return readStaticField(field, false);
 188  
     }
 189  
 
 190  
     /**
 191  
      * Reads a static Field.
 192  
      * @param field to read
 193  
      * @param forceAccess  whether to break scope restrictions using the
 194  
      *  <code>setAccessible</code> method.
 195  
      * @return the field value
 196  
      * @throws IllegalArgumentException if the field is null or not static
 197  
      * @throws IllegalAccessException if the field is not made accessible
 198  
      */
 199  
     public static Object readStaticField(final Field field, final boolean forceAccess) throws IllegalAccessException {
 200  21
         if (field == null) {
 201  2
             throw new IllegalArgumentException("The field must not be null");
 202  
         }
 203  19
         if (!Modifier.isStatic(field.getModifiers())) {
 204  4
             throw new IllegalArgumentException("The field '" + field.getName() + "' is not static");
 205  
         }
 206  15
         return readField(field, (Object) null, forceAccess);
 207  
     }
 208  
 
 209  
     /**
 210  
      * Reads the named public static field. Superclasses will be considered.
 211  
      * @param cls  the class to reflect, must not be null
 212  
      * @param fieldName  the field name to obtain
 213  
      * @return the value of the field
 214  
      * @throws IllegalArgumentException if the class is null, the field name is null or if the field could not be found
 215  
      * @throws IllegalAccessException if the field is not accessible
 216  
      */
 217  
     public static Object readStaticField(final Class<?> cls, final String fieldName) throws IllegalAccessException {
 218  8
         return readStaticField(cls, fieldName, false);
 219  
     }
 220  
 
 221  
     /**
 222  
      * Reads the named static field. Superclasses will be considered.
 223  
      * @param cls  the class to reflect, must not be null
 224  
      * @param fieldName  the field name to obtain
 225  
      * @param forceAccess  whether to break scope restrictions using the
 226  
      *  <code>setAccessible</code> method. <code>False</code> will only
 227  
      *  match public fields.
 228  
      * @return the Field object
 229  
      * @throws IllegalArgumentException if the class is null, the field name is null or if the field could not be found
 230  
      * @throws IllegalAccessException if the field is not made accessible
 231  
      */
 232  
     public static Object readStaticField(final Class<?> cls, final String fieldName, final boolean forceAccess)
 233  
         throws IllegalAccessException {
 234  16
         final Field field = getField(cls, fieldName, forceAccess);
 235  12
         if (field == null) {
 236  2
             throw new IllegalArgumentException("Cannot locate field " + fieldName + " on " + cls);
 237  
         }
 238  
         //already forced access above, don't repeat it here:
 239  10
         return readStaticField(field, false);
 240  
     }
 241  
 
 242  
     /**
 243  
      * Gets a static Field value by name. The field must be public.
 244  
      * Only the specified class will be considered.
 245  
      *
 246  
      * @param cls  the class to reflect, must not be null
 247  
      * @param fieldName  the field name to obtain
 248  
      * @return the value of the field
 249  
      * @throws IllegalArgumentException if the class is null, the field name is null or if the field could not be found
 250  
      * @throws IllegalAccessException if the field is not accessible
 251  
      */
 252  
     public static Object readDeclaredStaticField(final Class<?> cls, final String fieldName) throws IllegalAccessException {
 253  4
         return readDeclaredStaticField(cls, fieldName, false);
 254  
     }
 255  
 
 256  
     /**
 257  
      * Gets a static Field value by name. Only the specified class will
 258  
      * be considered.
 259  
      *
 260  
      * @param cls  the class to reflect, must not be null
 261  
      * @param fieldName  the field name to obtain
 262  
      * @param forceAccess  whether to break scope restrictions using the
 263  
      *  <code>setAccessible</code> method. <code>False</code> will only
 264  
      *  match public fields.
 265  
      * @return the Field object
 266  
      * @throws IllegalArgumentException if the class is null, the field name is null or if the field could not be found
 267  
      * @throws IllegalAccessException if the field is not made accessible
 268  
      */
 269  
     public static Object readDeclaredStaticField(final Class<?> cls, final String fieldName, final boolean forceAccess)
 270  
             throws IllegalAccessException {
 271  8
         final Field field = getDeclaredField(cls, fieldName, forceAccess);
 272  8
         if (field == null) {
 273  5
             throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName);
 274  
         }
 275  
         //already forced access above, don't repeat it here:
 276  3
         return readStaticField(field, false);
 277  
     }
 278  
 
 279  
     /**
 280  
      * Reads an accessible Field.
 281  
      * @param field  the field to use
 282  
      * @param target  the object to call on, may be null for static fields
 283  
      * @return the field value
 284  
      * @throws IllegalArgumentException if the field is null
 285  
      * @throws IllegalAccessException if the field is not accessible
 286  
      */
 287  
     public static Object readField(final Field field, final Object target) throws IllegalAccessException {
 288  73
         return readField(field, target, false);
 289  
     }
 290  
 
 291  
     /**
 292  
      * Reads a Field.
 293  
      * @param field  the field to use
 294  
      * @param target  the object to call on, may be null for static fields
 295  
      * @param forceAccess  whether to break scope restrictions using the
 296  
      *  <code>setAccessible</code> method.
 297  
      * @return the field value
 298  
      * @throws IllegalArgumentException if the field is null
 299  
      * @throws IllegalAccessException if the field is not made accessible
 300  
      */
 301  
     public static Object readField(final Field field, final Object target, final boolean forceAccess) throws IllegalAccessException {
 302  101
         if (field == null) {
 303  2
             throw new IllegalArgumentException("The field must not be null");
 304  
         }
 305  99
         if (forceAccess && !field.isAccessible()) {
 306  4
             field.setAccessible(true);
 307  
         } else {
 308  95
             MemberUtils.setAccessibleWorkaround(field);
 309  
         }
 310  99
         return field.get(target);
 311  
     }
 312  
 
 313  
     /**
 314  
      * Reads the named public field. Superclasses will be considered.
 315  
      * @param target  the object to reflect, must not be null
 316  
      * @param fieldName  the field name to obtain
 317  
      * @return the value of the field
 318  
      * @throws IllegalArgumentException if the class or field name is null
 319  
      * @throws IllegalAccessException if the named field is not public
 320  
      */
 321  
     public static Object readField(final Object target, final String fieldName) throws IllegalAccessException {
 322  20
         return readField(target, fieldName, false);
 323  
     }
 324  
 
 325  
     /**
 326  
      * Reads the named field. Superclasses will be considered.
 327  
      * @param target  the object to reflect, must not be null
 328  
      * @param fieldName  the field name to obtain
 329  
      * @param forceAccess  whether to break scope restrictions using the
 330  
      *  <code>setAccessible</code> method. <code>False</code> will only
 331  
      *  match public fields.
 332  
      * @return the field value
 333  
      * @throws IllegalArgumentException if the class or field name is null
 334  
      * @throws IllegalAccessException if the named field is not made accessible
 335  
      */
 336  
     public static Object readField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException {
 337  46
         if (target == null) {
 338  2
             throw new IllegalArgumentException("target object must not be null");
 339  
         }
 340  44
         final Class<?> cls = target.getClass();
 341  44
         final Field field = getField(cls, fieldName, forceAccess);
 342  42
         if (field == null) {
 343  6
             throw new IllegalArgumentException("Cannot locate field " + fieldName + " on " + cls);
 344  
         }
 345  
         //already forced access above, don't repeat it here:
 346  36
         return readField(field, target);
 347  
     }
 348  
 
 349  
     /**
 350  
      * Reads the named public field. Only the class of the specified object will be considered.
 351  
      * @param target  the object to reflect, must not be null
 352  
      * @param fieldName  the field name to obtain
 353  
      * @return the value of the field
 354  
      * @throws IllegalArgumentException if the class or field name is null
 355  
      * @throws IllegalAccessException if the named field is not public
 356  
      */
 357  
     public static Object readDeclaredField(final Object target, final String fieldName) throws IllegalAccessException {
 358  18
         return readDeclaredField(target, fieldName, false);
 359  
     }
 360  
 
 361  
     /**
 362  
      * <p<>Gets a Field value by name. Only the class of the specified
 363  
      * object will be considered.
 364  
      *
 365  
      * @param target  the object to reflect, must not be null
 366  
      * @param fieldName  the field name to obtain
 367  
      * @param forceAccess  whether to break scope restrictions using the
 368  
      *  <code>setAccessible</code> method. <code>False</code> will only
 369  
      *  match public fields.
 370  
      * @return the Field object
 371  
      * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null
 372  
      * @throws IllegalAccessException if the field is not made accessible
 373  
      */
 374  
     public static Object readDeclaredField(final Object target, final String fieldName, final boolean forceAccess)
 375  
         throws IllegalAccessException {
 376  40
         if (target == null) {
 377  2
             throw new IllegalArgumentException("target object must not be null");
 378  
         }
 379  38
         final Class<?> cls = target.getClass();
 380  38
         final Field field = getDeclaredField(cls, fieldName, forceAccess);
 381  36
         if (field == null) {
 382  12
             throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName);
 383  
         }
 384  
         //already forced access above, don't repeat it here:
 385  24
         return readField(field, target);
 386  
     }
 387  
 
 388  
     /**
 389  
      * Writes a public static Field.
 390  
      * @param field to write
 391  
      * @param value to set
 392  
      * @throws IllegalArgumentException if the field is null or not static
 393  
      * @throws IllegalAccessException if the field is not public or is final
 394  
      */
 395  
     public static void writeStaticField(final Field field, final Object value) throws IllegalAccessException {
 396  19
         writeStaticField(field, value, false);
 397  7
     }
 398  
 
 399  
     /**
 400  
      * Writes a static Field.
 401  
      * @param field to write
 402  
      * @param value to set
 403  
      * @param forceAccess  whether to break scope restrictions using the
 404  
      *  <code>setAccessible</code> method. <code>False</code> will only
 405  
      *  match public fields.
 406  
      * @throws IllegalArgumentException if the field is null or not static
 407  
      * @throws IllegalAccessException if the field is not made accessible or is final
 408  
      */
 409  
     public static void writeStaticField(final Field field, final Object value, final boolean forceAccess) throws IllegalAccessException {
 410  27
         if (field == null) {
 411  0
             throw new IllegalArgumentException("The field must not be null");
 412  
         }
 413  27
         if (!Modifier.isStatic(field.getModifiers())) {
 414  0
             throw new IllegalArgumentException("The field '" + field.getName() + "' is not static");
 415  
         }
 416  27
         writeField(field, (Object) null, value, forceAccess);
 417  11
     }
 418  
 
 419  
     /**
 420  
      * Writes a named public static Field. Superclasses will be considered.
 421  
      * @param cls Class on which the Field is to be found
 422  
      * @param fieldName to write
 423  
      * @param value to set
 424  
      * @throws IllegalArgumentException if the field cannot be located or is not static
 425  
      * @throws IllegalAccessException if the field is not public or is final
 426  
      */
 427  
     public static void writeStaticField(final Class<?> cls, final String fieldName, final Object value) throws IllegalAccessException {
 428  9
         writeStaticField(cls, fieldName, value, false);
 429  2
     }
 430  
 
 431  
     /**
 432  
      * Writes a named static Field. Superclasses will be considered.
 433  
      * @param cls Class on which the Field is to be found
 434  
      * @param fieldName to write
 435  
      * @param value to set
 436  
      * @param forceAccess  whether to break scope restrictions using the
 437  
      *  <code>setAccessible</code> method. <code>False</code> will only
 438  
      *  match public fields.
 439  
      * @throws IllegalArgumentException if the field cannot be located or is not static
 440  
      * @throws IllegalAccessException if the field is not made accessible or is final
 441  
      */
 442  
     public static void writeStaticField(final Class<?> cls, final String fieldName, final Object value, final boolean forceAccess)
 443  
             throws IllegalAccessException {
 444  17
         final Field field = getField(cls, fieldName, forceAccess);
 445  17
         if (field == null) {
 446  6
             throw new IllegalArgumentException("Cannot locate field " + fieldName + " on " + cls);
 447  
         }
 448  
         //already forced access above, don't repeat it here:
 449  11
         writeStaticField(field, value);
 450  6
     }
 451  
 
 452  
     /**
 453  
      * Writes a named public static Field. Only the specified class will be considered.
 454  
      * @param cls Class on which the Field is to be found
 455  
      * @param fieldName to write
 456  
      * @param value to set
 457  
      * @throws IllegalArgumentException if the field cannot be located or is not static
 458  
      * @throws IllegalAccessException if the field is not public or is final
 459  
      */
 460  
     public static void writeDeclaredStaticField(final Class<?> cls, final String fieldName, final Object value)
 461  
             throws IllegalAccessException {
 462  7
         writeDeclaredStaticField(cls, fieldName, value, false);
 463  0
     }
 464  
 
 465  
     /**
 466  
      * Writes a named static Field. Only the specified class will be considered.
 467  
      * @param cls Class on which the Field is to be found
 468  
      * @param fieldName to write
 469  
      * @param value to set
 470  
      * @param forceAccess  whether to break scope restrictions using the
 471  
      *  <code>setAccessible</code> method. <code>False</code> will only
 472  
      *  match public fields.
 473  
      * @throws IllegalArgumentException if the field cannot be located or is not static
 474  
      * @throws IllegalAccessException if the field is not made accessible or is final
 475  
       */
 476  
     public static void writeDeclaredStaticField(final Class<?> cls, final String fieldName, final Object value, final boolean forceAccess)
 477  
             throws IllegalAccessException {
 478  15
         final Field field = getDeclaredField(cls, fieldName, forceAccess);
 479  15
         if (field == null) {
 480  6
             throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName);
 481  
         }
 482  
         //already forced access above, don't repeat it here:
 483  9
         writeField(field, (Object) null, value);
 484  4
     }
 485  
 
 486  
     /**
 487  
      * Writes an accessible field.
 488  
      * @param field to write
 489  
      * @param target  the object to call on, may be null for static fields
 490  
      * @param value to set
 491  
      * @throws IllegalArgumentException if the field is null
 492  
      * @throws IllegalAccessException if the field is not accessible or is final
 493  
      */
 494  
     public static void writeField(final Field field, final Object target, final Object value) throws IllegalAccessException {
 495  43
         writeField(field, target, value, false);
 496  35
     }
 497  
 
 498  
     /**
 499  
      * Writes a field.
 500  
      * @param field to write
 501  
      * @param target  the object to call on, may be null for static fields
 502  
      * @param value to set
 503  
      * @param forceAccess  whether to break scope restrictions using the
 504  
      *  <code>setAccessible</code> method. <code>False</code> will only
 505  
      *  match public fields.
 506  
      * @throws IllegalArgumentException if the field is null
 507  
      * @throws IllegalAccessException if the field is not made accessible or is final
 508  
      */
 509  
     public static void writeField(final Field field, final Object target, final Object value, final boolean forceAccess)
 510  
         throws IllegalAccessException {
 511  74
         if (field == null) {
 512  0
             throw new IllegalArgumentException("The field must not be null");
 513  
         }
 514  74
         if (forceAccess && !field.isAccessible()) {
 515  12
             field.setAccessible(true);
 516  
         } else {
 517  62
             MemberUtils.setAccessibleWorkaround(field);
 518  
         }
 519  74
         field.set(target, value);
 520  50
     }
 521  
 
 522  
     /**
 523  
      * Writes a public field. Superclasses will be considered.
 524  
      * @param target  the object to reflect, must not be null
 525  
      * @param fieldName  the field name to obtain
 526  
      * @param value to set
 527  
      * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null
 528  
      * @throws IllegalAccessException if the field is not accessible
 529  
      */
 530  
     public static void writeField(final Object target, final String fieldName, final Object value) throws IllegalAccessException {
 531  12
         writeField(target, fieldName, value, false);
 532  6
     }
 533  
 
 534  
     /**
 535  
      * Writes a field. Superclasses will be considered.
 536  
      * @param target  the object to reflect, must not be null
 537  
      * @param fieldName  the field name to obtain
 538  
      * @param value to set
 539  
      * @param forceAccess  whether to break scope restrictions using the
 540  
      *  <code>setAccessible</code> method. <code>False</code> will only
 541  
      *  match public fields.
 542  
      * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null
 543  
      * @throws IllegalAccessException if the field is not made accessible
 544  
      */
 545  
     public static void writeField(final Object target, final String fieldName, final Object value, final boolean forceAccess)
 546  
             throws IllegalAccessException {
 547  24
         if (target == null) {
 548  0
             throw new IllegalArgumentException("target object must not be null");
 549  
         }
 550  24
         final Class<?> cls = target.getClass();
 551  24
         final Field field = getField(cls, fieldName, forceAccess);
 552  24
         if (field == null) {
 553  6
             throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName);
 554  
         }
 555  
         //already forced access above, don't repeat it here:
 556  18
         writeField(field, target, value);
 557  18
     }
 558  
 
 559  
     /**
 560  
      * Writes a public field. Only the specified class will be considered.
 561  
      * @param target  the object to reflect, must not be null
 562  
      * @param fieldName  the field name to obtain
 563  
      * @param value to set
 564  
      * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null
 565  
      * @throws IllegalAccessException if the field is not made accessible
 566  
      */
 567  
     public static void writeDeclaredField(final Object target, final String fieldName, final Object value) throws IllegalAccessException {
 568  12
         writeDeclaredField(target, fieldName, value, false);
 569  4
     }
 570  
 
 571  
     /**
 572  
      * Writes a public field. Only the specified class will be considered.
 573  
      * @param target  the object to reflect, must not be null
 574  
      * @param fieldName  the field name to obtain
 575  
      * @param value to set
 576  
      * @param forceAccess  whether to break scope restrictions using the
 577  
      *  <code>setAccessible</code> method. <code>False</code> will only
 578  
      *  match public fields.
 579  
      * @throws IllegalArgumentException if <code>target</code> or <code>fieldName</code> is null
 580  
      * @throws IllegalAccessException if the field is not made accessible
 581  
      */
 582  
     public static void writeDeclaredField(final Object target, final String fieldName, final Object value, final boolean forceAccess)
 583  
             throws IllegalAccessException {
 584  24
         if (target == null) {
 585  0
             throw new IllegalArgumentException("target object must not be null");
 586  
         }
 587  24
         final Class<?> cls = target.getClass();
 588  24
         final Field field = getDeclaredField(cls, fieldName, forceAccess);
 589  24
         if (field == null) {
 590  12
             throw new IllegalArgumentException("Cannot locate declared field " + cls.getName() + "." + fieldName);
 591  
         }
 592  
         //already forced access above, don't repeat it here:
 593  12
         writeField(field, target, value);
 594  12
     }
 595  
 }