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 * 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 * 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 * if the class is {@code null}. 093 * @throws IllegalArgumentException 094 * if the field name is {@code null}, blank, or empty. 095 * @throws SecurityException 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 * 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}