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