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 * @since 2.5 044 */ 045public class FieldUtils { 046 047 /** 048 * Gets all fields of the given class and its parents (if any). 049 * 050 * @param cls 051 * the {@link Class} to query 052 * @return an array of Fields (possibly empty). 053 * @throws NullPointerException 054 * if the class is {@code null}. 055 * @since 3.2 056 */ 057 public static Field[] getAllFields(final Class<?> cls) { 058 return getAllFieldsList(cls).toArray(ArrayUtils.EMPTY_FIELD_ARRAY); 059 } 060 061 /** 062 * Gets all fields of the given class and its parents (if any). 063 * 064 * @param cls 065 * the {@link Class} to query 066 * @return a list of Fields (possibly empty). 067 * @throws NullPointerException 068 * if the class is {@code null}. 069 * @since 3.2 070 */ 071 public static List<Field> getAllFieldsList(final Class<?> cls) { 072 Objects.requireNonNull(cls, "cls"); 073 final List<Field> allFields = new ArrayList<>(); 074 Class<?> currentClass = cls; 075 while (currentClass != null) { 076 Collections.addAll(allFields, currentClass.getDeclaredFields()); 077 currentClass = currentClass.getSuperclass(); 078 } 079 return allFields; 080 } 081 082 /** 083 * Gets an accessible {@link Field} by name respecting scope. Only the specified class will be considered. 084 * 085 * @param cls 086 * the {@link Class} to reflect, must not be {@code null} 087 * @param fieldName 088 * the field name to obtain. 089 * @return the Field object. 090 * @throws NullPointerException 091 * if the class is {@code null}. 092 * @throws IllegalArgumentException 093 * if the field name is {@code null}, blank, or empty. 094 * @throws SecurityException if an underlying accessible object's method denies the request. 095 * @see SecurityManager#checkPermission 096 */ 097 public static Field getDeclaredField(final Class<?> cls, final String fieldName) { 098 return getDeclaredField(cls, fieldName, false); 099 } 100 101 /** 102 * Gets an accessible {@link Field} by name, breaking scope if requested. Only the specified class will be 103 * considered. 104 * 105 * @param cls 106 * the {@link Class} to reflect, must not be {@code null}. 107 * @param fieldName 108 * the field name to obtain. 109 * @param forceAccess 110 * whether to break scope restrictions using the 111 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 112 * match {@code public} fields. 113 * @return the Field object 114 * @throws NullPointerException 115 * if the class is {@code null}. 116 * @throws IllegalArgumentException 117 * if the field name is {@code null}, blank, or empty. 118 * @throws SecurityException if an underlying accessible object's method denies the request. 119 * @see SecurityManager#checkPermission 120 */ 121 public static Field getDeclaredField(final Class<?> cls, final String fieldName, final boolean forceAccess) { 122 Objects.requireNonNull(cls, "cls"); 123 Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty"); 124 try { 125 // only consider the specified class by using getDeclaredField() 126 final Field field = cls.getDeclaredField(fieldName); 127 if (!MemberUtils.isAccessible(field)) { 128 if (!forceAccess) { 129 return null; 130 } 131 field.setAccessible(true); 132 } 133 return field; 134 } catch (final NoSuchFieldException ignored) { 135 // ignore 136 } 137 return null; 138 } 139 140 /** 141 * Gets an accessible {@link Field} by name respecting scope. Superclasses/interfaces will be considered. 142 * 143 * @param cls 144 * the {@link Class} to reflect, must not be {@code null}. 145 * @param fieldName 146 * the field name to obtain. 147 * @return the Field object. 148 * @throws NullPointerException 149 * if the class is {@code null}. 150 * @throws IllegalArgumentException 151 * if the field name is {@code null}, blank, or empty 152 * @throws SecurityException 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 if the class is {@code null}. 173 * @throws IllegalArgumentException if the field name is blank or empty or is matched at multiple places 174 * in the inheritance hierarchy. 175 * @throws SecurityException 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 // incase 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, 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 * @param cls 232 * the {@link Class} to query. 233 * @param annotationCls 234 * the {@link Annotation} that must be present on a field to be matched. 235 * @return a list of Fields (possibly empty). 236 * @throws NullPointerException 237 * if the class or annotation are {@code null}. 238 * @since 3.4 239 */ 240 public static List<Field> getFieldsListWithAnnotation(final Class<?> cls, final Class<? extends Annotation> annotationCls) { 241 Objects.requireNonNull(annotationCls, "annotationCls"); 242 return getAllFieldsList(cls).stream().filter(field -> field.getAnnotation(annotationCls) != null).collect(Collectors.toList()); 243 } 244 245 /** 246 * Gets all fields of the given class and its parents (if any) that are annotated with the given annotation. 247 * @param cls 248 * the {@link Class} to query. 249 * @param annotationCls 250 * the {@link Annotation} that must be present on a field to be matched 251 * @return an array of Fields (possibly empty). 252 * @throws NullPointerException 253 * if the class or annotation are {@code null}. 254 * @since 3.4 255 */ 256 public static Field[] getFieldsWithAnnotation(final Class<?> cls, final Class<? extends Annotation> annotationCls) { 257 return getFieldsListWithAnnotation(cls, annotationCls).toArray(ArrayUtils.EMPTY_FIELD_ARRAY); 258 } 259 260 /** 261 * Reads the named {@code public} {@link Field}. Only the class of the specified object will be considered. 262 * 263 * @param target 264 * the object to reflect, must not be {@code null}. 265 * @param fieldName 266 * the field name to obtain. 267 * @return the value of the field. 268 * @throws NullPointerException 269 * if {@code target} is {@code null}. 270 * @throws IllegalArgumentException 271 * if {@code fieldName} is {@code null}, blank or empty, or could not be found. 272 * @throws IllegalAccessException 273 * if the named field is not {@code public} 274 * @throws SecurityException if an underlying accessible object's method denies the request. 275 * @see SecurityManager#checkPermission 276 */ 277 public static Object readDeclaredField(final Object target, final String fieldName) throws IllegalAccessException { 278 return readDeclaredField(target, fieldName, false); 279 } 280 281 /** 282 * Gets a {@link Field} value by name. Only the class of the specified object will be considered. 283 * 284 * @param target 285 * the object to reflect, must not be {@code null}. 286 * @param fieldName 287 * the field name to obtain. 288 * @param forceAccess 289 * whether to break scope restrictions using the 290 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 291 * match public fields. 292 * @return the Field object. 293 * @throws NullPointerException 294 * if {@code target} is {@code null}. 295 * @throws IllegalArgumentException 296 * if {@code fieldName} is {@code null}, blank or empty, or could not be found. 297 * @throws IllegalAccessException 298 * if the field is not made accessible. 299 * @throws SecurityException if an underlying accessible object's method denies the request. 300 * @see SecurityManager#checkPermission 301 */ 302 public static Object readDeclaredField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException { 303 Objects.requireNonNull(target, "target"); 304 final Class<?> cls = target.getClass(); 305 final Field field = getDeclaredField(cls, fieldName, forceAccess); 306 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls, fieldName); 307 // already forced access above, don't repeat it here: 308 return readField(field, target, false); 309 } 310 311 /** 312 * Gets the value of a {@code static} {@link Field} by name. The field must be {@code public}. Only the specified 313 * class will be considered. 314 * 315 * @param cls 316 * the {@link Class} to reflect, must not be {@code null}. 317 * @param fieldName 318 * the field name to obtain. 319 * @return the value of the field. 320 * @throws NullPointerException 321 * if the class is {@code null}, or the field could not be found. 322 * @throws IllegalArgumentException 323 * if the field name is {@code null}, blank, empty, or is not {@code static}. 324 * @throws IllegalAccessException 325 * if the field is not accessible 326 * @throws SecurityException 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 * if the class is {@code null}, or the field could not be found. 347 * @throws IllegalArgumentException 348 * if the field name is blank or empty, is not {@code static}. 349 * @throws IllegalAccessException 350 * if the field is not made accessible 351 * @throws SecurityException if an underlying accessible object's method denies the request. 352 * @see SecurityManager#checkPermission 353 */ 354 public static Object readDeclaredStaticField(final Class<?> cls, final String fieldName, final boolean forceAccess) throws IllegalAccessException { 355 final Field field = getDeclaredField(cls, fieldName, forceAccess); 356 Validate.notNull(field, "Cannot locate declared field %s.%s", cls.getName(), fieldName); 357 // already forced access above, don't repeat it here: 358 return readStaticField(field, false); 359 } 360 361 /** 362 * Reads an accessible {@link Field}. 363 * 364 * @param field 365 * the field to use. 366 * @param target 367 * the object to call on, may be {@code null} for {@code static} fields. 368 * @return the field value 369 * @throws NullPointerException 370 * if the field is {@code null}. 371 * @throws IllegalAccessException 372 * if the field is not accessible. 373 * @throws SecurityException if an underlying accessible object's method denies the request. 374 * @see SecurityManager#checkPermission 375 */ 376 public static Object readField(final Field field, final Object target) throws IllegalAccessException { 377 return readField(field, target, false); 378 } 379 380 /** 381 * Reads a {@link Field}. 382 * 383 * @param field 384 * the field to use. 385 * @param target 386 * the object to call on, may be {@code null} for {@code static} fields. 387 * @param forceAccess 388 * whether to break scope restrictions using the 389 * {@link AccessibleObject#setAccessible(boolean)} method. 390 * @return the field value 391 * @throws NullPointerException 392 * if the field is {@code null}. 393 * @throws IllegalAccessException 394 * if the field is not made accessible. 395 * @throws SecurityException if an underlying accessible object's method denies the request. 396 * @see SecurityManager#checkPermission 397 * @throws SecurityException if an underlying accessible object's method denies the request. 398 * @see SecurityManager#checkPermission 399 */ 400 public static Object readField(final Field field, final Object target, final boolean forceAccess) throws IllegalAccessException { 401 Objects.requireNonNull(field, "field"); 402 if (forceAccess && !field.isAccessible()) { 403 field.setAccessible(true); 404 } else { 405 MemberUtils.setAccessibleWorkaround(field); 406 } 407 return field.get(target); 408 } 409 410 /** 411 * Reads the named {@code public} {@link Field}. Superclasses will be considered. 412 * 413 * @param target 414 * the object to reflect, must not be {@code null}. 415 * @param fieldName 416 * the field name to obtain. 417 * @return the value of the field. 418 * @throws NullPointerException 419 * if the target is {@code null}. 420 * @throws IllegalArgumentException 421 * if the field name is {@code null}, blank, empty, or could not be found. 422 * @throws IllegalAccessException 423 * if the named field is not {@code public}. 424 * @throws SecurityException if an underlying accessible object's method denies the request. 425 * @see SecurityManager#checkPermission 426 */ 427 public static Object readField(final Object target, final String fieldName) throws IllegalAccessException { 428 return readField(target, fieldName, false); 429 } 430 431 /** 432 * Reads the named {@link Field}. Superclasses will be considered. 433 * 434 * @param target 435 * the object to reflect, must not be {@code null}. 436 * @param fieldName 437 * the field name to obtain. 438 * @param forceAccess 439 * whether to break scope restrictions using the 440 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 441 * match {@code public} fields. 442 * @return the field value 443 * @throws NullPointerException 444 * if {@code target} is {@code null}. 445 * @throws IllegalArgumentException 446 * if the field name is {@code null}, blank, empty, or could not be found. 447 * @throws IllegalAccessException 448 * if the named field is not made accessible. 449 * @throws SecurityException if an underlying accessible object's method denies the request. 450 * @see SecurityManager#checkPermission 451 */ 452 public static Object readField(final Object target, final String fieldName, final boolean forceAccess) throws IllegalAccessException { 453 Objects.requireNonNull(target, "target"); 454 final Class<?> cls = target.getClass(); 455 final Field field = getField(cls, fieldName, forceAccess); 456 Validate.isTrue(field != null, "Cannot locate field %s on %s", fieldName, cls); 457 // already forced access above, don't repeat it here: 458 return readField(field, target, false); 459 } 460 461 /** 462 * Reads the named {@code public static} {@link Field}. Superclasses will be considered. 463 * 464 * @param cls 465 * the {@link Class} to reflect, must not be {@code null}. 466 * @param fieldName 467 * the field name to obtain. 468 * @return the value of the field. 469 * @throws NullPointerException 470 * if the class is {@code null}, or the field could not be found. 471 * @throws IllegalArgumentException 472 * if the field name is {@code null}, blank or empty, or is not {@code static}. 473 * @throws IllegalAccessException 474 * if the field is not accessible. 475 * @throws SecurityException if an underlying accessible object's method denies the request. 476 * @see SecurityManager#checkPermission 477 */ 478 public static Object readStaticField(final Class<?> cls, final String fieldName) throws IllegalAccessException { 479 return readStaticField(cls, fieldName, false); 480 } 481 482 /** 483 * Reads the named {@code static} {@link Field}. Superclasses will be considered. 484 * 485 * @param cls 486 * the {@link Class} to reflect, must not be {@code null}. 487 * @param fieldName 488 * the field name to obtain. 489 * @param forceAccess 490 * whether to break scope restrictions using the 491 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 492 * match {@code public} fields. 493 * @return the Field object. 494 * @throws NullPointerException 495 * if the class is {@code null}, or the field could not be found. 496 * @throws IllegalArgumentException 497 * if the field name is {@code null}, blank or empty, or is not {@code static}. 498 * @throws IllegalAccessException 499 * if the field is not made accessible. 500 * @throws SecurityException if an underlying accessible object's method denies the request. 501 * @see SecurityManager#checkPermission 502 */ 503 public static Object readStaticField(final Class<?> cls, final String fieldName, final boolean forceAccess) throws IllegalAccessException { 504 final Field field = getField(cls, fieldName, forceAccess); 505 Validate.notNull(field, "Cannot locate field '%s' on %s", fieldName, cls); 506 // already forced access above, don't repeat it here: 507 return readStaticField(field, false); 508 } 509 510 /** 511 * Reads an accessible {@code static} {@link Field}. 512 * 513 * @param field 514 * to read. 515 * @return the field value. 516 * @throws NullPointerException 517 * if the field is {@code null}. 518 * @throws IllegalArgumentException 519 * if the field is not {@code static}. 520 * @throws IllegalAccessException 521 * if the field is not accessible 522 * @throws SecurityException if an underlying accessible object's method denies the request. 523 * @see SecurityManager#checkPermission 524 */ 525 public static Object readStaticField(final Field field) throws IllegalAccessException { 526 return readStaticField(field, false); 527 } 528 529 /** 530 * Reads a static {@link Field}. 531 * 532 * @param field 533 * to read. 534 * @param forceAccess 535 * whether to break scope restrictions using the 536 * {@link AccessibleObject#setAccessible(boolean)} method. 537 * @return the field value. 538 * @throws NullPointerException 539 * if the field is {@code null}. 540 * @throws IllegalArgumentException 541 * if the field is not {@code static}. 542 * @throws IllegalAccessException 543 * if the field is not made accessible. 544 * @throws SecurityException if an underlying accessible object's method denies the request. 545 * @see SecurityManager#checkPermission 546 */ 547 public static Object readStaticField(final Field field, final boolean forceAccess) throws IllegalAccessException { 548 Objects.requireNonNull(field, "field"); 549 Validate.isTrue(MemberUtils.isStatic(field), "The field '%s' is not static", field.getName()); 550 return readField(field, (Object) null, forceAccess); 551 } 552 553 /** 554 * Removes the final modifier from a {@link Field}. 555 * 556 * @param field 557 * to remove the final modifier. 558 * @throws NullPointerException 559 * if the field is {@code null}. 560 * @throws SecurityException if an underlying accessible object's method denies the request. 561 * @see SecurityManager#checkPermission 562 * @since 3.2 563 */ 564 public static void removeFinalModifier(final Field field) { 565 removeFinalModifier(field, true); 566 } 567 568 /** 569 * Removes the final modifier from a {@link Field}. 570 * 571 * @param field 572 * to remove the final modifier. 573 * @param forceAccess 574 * whether to break scope restrictions using the 575 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 576 * match {@code public} fields. 577 * @throws NullPointerException 578 * if the field is {@code null}. 579 * @throws SecurityException if an underlying accessible object's method denies the request. 580 * @see SecurityManager#checkPermission 581 * @deprecated As of Java 12, we can no longer drop the {@code final} modifier, thus 582 * rendering this method obsolete. The JDK discussion about this change can be found 583 * here: https://mail.openjdk.java.net/pipermail/core-libs-dev/2018-November/056486.html 584 * @since 3.3 585 */ 586 @Deprecated 587 public static void removeFinalModifier(final Field field, final boolean forceAccess) { 588 Objects.requireNonNull(field, "field"); 589 590 try { 591 if (Modifier.isFinal(field.getModifiers())) { 592 // Do all JREs implement Field with a private ivar called "modifiers"? 593 final Field modifiersField = Field.class.getDeclaredField("modifiers"); 594 final boolean doForceAccess = forceAccess && !modifiersField.isAccessible(); 595 if (doForceAccess) { 596 modifiersField.setAccessible(true); 597 } 598 try { 599 modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 600 } finally { 601 if (doForceAccess) { 602 modifiersField.setAccessible(false); 603 } 604 } 605 } 606 } catch (final NoSuchFieldException | IllegalAccessException e) { 607 if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_12)) { 608 throw new UnsupportedOperationException( 609 "In java 12+ final cannot be removed.", 610 e 611 ); 612 } 613 // else no exception is thrown because we can modify final. 614 } 615 } 616 617 /** 618 * Writes a {@code public} {@link Field}. Only the specified class will be considered. 619 * 620 * @param target 621 * the object to reflect, must not be {@code null}. 622 * @param fieldName 623 * the field name to obtain. 624 * @param value 625 * the new value. 626 * @throws NullPointerException 627 * if {@code target} is {@code null}. 628 * @throws IllegalArgumentException 629 * if {@code fieldName} is {@code null}, blank or empty, or could not be found, 630 * or {@code value} is not assignable. 631 * @throws IllegalAccessException 632 * if the field is not made accessible 633 * @throws SecurityException if an underlying accessible object's method denies the request. 634 * @see SecurityManager#checkPermission 635 */ 636 public static void writeDeclaredField(final Object target, final String fieldName, final Object value) throws IllegalAccessException { 637 writeDeclaredField(target, fieldName, value, false); 638 } 639 640 /** 641 * Writes a {@code public} {@link Field}. Only the specified class will be considered. 642 * 643 * @param target 644 * the object to reflect, must not be {@code null}. 645 * @param fieldName 646 * the field name to obtain. 647 * @param value 648 * the new value. 649 * @param forceAccess 650 * whether to break scope restrictions using the 651 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 652 * match {@code public} fields. 653 * @throws IllegalArgumentException 654 * if {@code fieldName} is {@code null}, blank or empty, or could not be found, 655 * or {@code value} is not assignable 656 * @throws IllegalAccessException 657 * if the field is not made accessible 658 * @throws SecurityException if an underlying accessible object's method denies the request. 659 * @see SecurityManager#checkPermission 660 */ 661 public static void writeDeclaredField(final Object target, final String fieldName, final Object value, final boolean forceAccess) 662 throws IllegalAccessException { 663 Objects.requireNonNull(target, "target"); 664 final Class<?> cls = target.getClass(); 665 final Field field = getDeclaredField(cls, fieldName, forceAccess); 666 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls.getName(), fieldName); 667 // already forced access above, don't repeat it here: 668 writeField(field, target, value, false); 669 } 670 671 /** 672 * Writes a named {@code public static} {@link Field}. Only the specified class will be considered. 673 * 674 * @param cls 675 * {@link Class} on which the field is to be found. 676 * @param fieldName 677 * to write. 678 * @param value 679 * the new value. 680 * @throws NullPointerException 681 * if {@code cls} is {@code null} or the field cannot be located. 682 * @throws IllegalArgumentException 683 * if the field name is {@code null}, blank, empty, not {@code static}, or {@code value} is not assignable. 684 * @throws IllegalAccessException 685 * if the field is not {@code public} or is {@code final} 686 * @throws SecurityException if an underlying accessible object's method denies the request. 687 * @see SecurityManager#checkPermission 688 */ 689 public static void writeDeclaredStaticField(final Class<?> cls, final String fieldName, final Object value) throws IllegalAccessException { 690 writeDeclaredStaticField(cls, fieldName, value, false); 691 } 692 693 /** 694 * Writes a named {@code static} {@link Field}. Only the specified class will be considered. 695 * 696 * @param cls 697 * {@link Class} on which the field is to be found. 698 * @param fieldName 699 * to write 700 * @param value 701 * the new value. 702 * @param forceAccess 703 * whether to break scope restrictions using the {@code AccessibleObject#setAccessible(boolean)} method. 704 * {@code false} will only match {@code public} fields. 705 * @throws NullPointerException 706 * if {@code cls} is {@code null} or the field cannot be located. 707 * @throws IllegalArgumentException 708 * if the field name is {@code null}, blank, empty, not {@code static}, or {@code value} is not assignable. 709 * @throws IllegalAccessException 710 * if the field is not made accessible or is {@code final} 711 * @throws SecurityException if an underlying accessible object's method denies the request. 712 * @see SecurityManager#checkPermission 713 */ 714 public static void writeDeclaredStaticField(final Class<?> cls, final String fieldName, final Object value, final boolean forceAccess) 715 throws IllegalAccessException { 716 final Field field = getDeclaredField(cls, fieldName, forceAccess); 717 Validate.notNull(field, "Cannot locate declared field %s.%s", cls.getName(), fieldName); 718 // already forced access above, don't repeat it here: 719 writeField(field, (Object) null, value, false); 720 } 721 722 /** 723 * Writes an accessible {@link Field}. 724 * 725 * @param field 726 * to write. 727 * @param target 728 * the object to call on, may be {@code null} for {@code static} fields. 729 * @param value 730 * the new value. 731 * @throws NullPointerException 732 * if the field is {@code null}. 733 * @throws IllegalArgumentException 734 * if {@code value} is not assignable. 735 * @throws IllegalAccessException 736 * if the field is not accessible or is {@code final}. 737 * @throws SecurityException if an underlying accessible object's method denies the request. 738 * @see SecurityManager#checkPermission 739 */ 740 public static void writeField(final Field field, final Object target, final Object value) throws IllegalAccessException { 741 writeField(field, target, value, false); 742 } 743 744 /** 745 * Writes a {@link Field}. 746 * 747 * @param field 748 * to write. 749 * @param target 750 * the object to call on, may be {@code null} for {@code static} fields 751 * @param value 752 * the new value. 753 * @param forceAccess 754 * whether to break scope restrictions using the 755 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 756 * match {@code public} fields. 757 * @throws NullPointerException 758 * if the field is {@code null}. 759 * @throws IllegalArgumentException 760 * if {@code value} is not assignable. 761 * @throws IllegalAccessException 762 * if the field is not made accessible or is {@code final} 763 * @throws SecurityException if an underlying accessible object's method denies the request. 764 * @see SecurityManager#checkPermission 765 */ 766 public static void writeField(final Field field, final Object target, final Object value, final boolean forceAccess) 767 throws IllegalAccessException { 768 Objects.requireNonNull(field, "field"); 769 if (forceAccess && !field.isAccessible()) { 770 field.setAccessible(true); 771 } else { 772 MemberUtils.setAccessibleWorkaround(field); 773 } 774 field.set(target, value); 775 } 776 777 /** 778 * Writes a {@code public} {@link Field}. Superclasses will be considered. 779 * 780 * @param target 781 * the object to reflect, must not be {@code null}. 782 * @param fieldName 783 * the field name to obtain. 784 * @param value 785 * the new value. 786 * @throws NullPointerException 787 * if {@code target} is {@code null}. 788 * @throws IllegalArgumentException 789 * if {@code fieldName} is {@code null}, blank, empty, or could not be found, 790 * or {@code value} is not assignable. 791 * @throws IllegalAccessException 792 * if the field is not accessible. 793 * @throws SecurityException if an underlying accessible object's method denies the request. 794 * @see SecurityManager#checkPermission 795 */ 796 public static void writeField(final Object target, final String fieldName, final Object value) throws IllegalAccessException { 797 writeField(target, fieldName, value, false); 798 } 799 800 /** 801 * Writes a {@link Field}. Superclasses will be considered. 802 * 803 * @param target 804 * the object to reflect, must not be {@code null}. 805 * @param fieldName 806 * the field name to obtain. 807 * @param value 808 * the new value. 809 * @param forceAccess 810 * whether to break scope restrictions using the 811 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 812 * match {@code public} fields. 813 * @throws NullPointerException 814 * if {@code target} is {@code null}. 815 * @throws IllegalArgumentException 816 * if {@code fieldName} is {@code null}, blank, empty, or could not be found, 817 * or {@code value} is not assignable. 818 * @throws IllegalAccessException 819 * if the field is not made accessible. 820 * @throws SecurityException if an underlying accessible object's method denies the request. 821 * @see SecurityManager#checkPermission 822 */ 823 public static void writeField(final Object target, final String fieldName, final Object value, final boolean forceAccess) 824 throws IllegalAccessException { 825 Objects.requireNonNull(target, "target"); 826 final Class<?> cls = target.getClass(); 827 final Field field = getField(cls, fieldName, forceAccess); 828 Validate.isTrue(field != null, "Cannot locate declared field %s.%s", cls.getName(), fieldName); 829 // already forced access above, don't repeat it here: 830 writeField(field, target, value, false); 831 } 832 833 /** 834 * Writes a named {@code public static} {@link Field}. Superclasses will be considered. 835 * 836 * @param cls 837 * {@link Class} on which the field is to be found. 838 * @param fieldName 839 * to write. 840 * @param value 841 * the new value. 842 * @throws NullPointerException 843 * if {@code target} is {@code null}. 844 * @throws IllegalArgumentException 845 * if {@code fieldName} is {@code null}, blank or empty, the field cannot be located or is 846 * not {@code static}, or {@code value} is not assignable. 847 * @throws IllegalAccessException 848 * if the field is not {@code public} or is {@code final} 849 * @throws SecurityException if an underlying accessible object's method denies the request. 850 * @see SecurityManager#checkPermission 851 */ 852 public static void writeStaticField(final Class<?> cls, final String fieldName, final Object value) throws IllegalAccessException { 853 writeStaticField(cls, fieldName, value, false); 854 } 855 856 /** 857 * Writes a named {@code static} {@link Field}. Superclasses will be considered. 858 * 859 * @param cls 860 * {@link Class} on which the field is to be found. 861 * @param fieldName 862 * to write. 863 * @param value 864 * the new value. 865 * @param forceAccess 866 * whether to break scope restrictions using the 867 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 868 * match {@code public} fields. 869 * @throws NullPointerException 870 * if {@code cls} is {@code null} or the field cannot be located. 871 * @throws IllegalArgumentException 872 * if {@code fieldName} is {@code null}, blank or empty, the field not {@code static}, or {@code value} is not assignable. 873 * @throws IllegalAccessException 874 * if the field is not made accessible or is {@code final}. 875 * @throws SecurityException if an underlying accessible object's method denies the request. 876 * @see SecurityManager#checkPermission 877 */ 878 public static void writeStaticField(final Class<?> cls, final String fieldName, final Object value, final boolean forceAccess) 879 throws IllegalAccessException { 880 final Field field = getField(cls, fieldName, forceAccess); 881 Validate.notNull(field, "Cannot locate field %s on %s", fieldName, cls); 882 // already forced access above, don't repeat it here: 883 writeStaticField(field, value, false); 884 } 885 886 /** 887 * Writes a {@code public static} {@link Field}. 888 * 889 * @param field 890 * to write. 891 * @param value 892 * the new value. 893 * @throws NullPointerException 894 * if the field is {@code null}. 895 * @throws IllegalArgumentException 896 * if the field is not {@code static}, or {@code value} is not assignable. 897 * @throws IllegalAccessException 898 * if the field is not {@code public} or is {@code final}. 899 * @throws SecurityException if an underlying accessible object's method denies the request. 900 * @see SecurityManager#checkPermission 901 */ 902 public static void writeStaticField(final Field field, final Object value) throws IllegalAccessException { 903 writeStaticField(field, value, false); 904 } 905 906 /** 907 * Writes a static {@link Field}. 908 * 909 * @param field 910 * to write. 911 * @param value 912 * the new value. 913 * @param forceAccess 914 * whether to break scope restrictions using the 915 * {@link AccessibleObject#setAccessible(boolean)} method. {@code false} will only 916 * match {@code public} fields. 917 * @throws NullPointerException 918 * if the field is {@code null}. 919 * @throws IllegalArgumentException 920 * if the field is not {@code static}, or {@code value} is not assignable. 921 * @throws IllegalAccessException 922 * if the field is not made accessible or is {@code final} 923 * @throws SecurityException if an underlying accessible object's method denies the request. 924 * @see SecurityManager#checkPermission 925 */ 926 public static void writeStaticField(final Field field, final Object value, final boolean forceAccess) throws IllegalAccessException { 927 Objects.requireNonNull(field, "field"); 928 Validate.isTrue(MemberUtils.isStatic(field), "The field %s.%s is not static", field.getDeclaringClass().getName(), 929 field.getName()); 930 writeField(field, (Object) null, value, forceAccess); 931 } 932 933 /** 934 * {@link FieldUtils} instances should NOT be constructed in standard programming. 935 * <p> 936 * This constructor is {@code public} to permit tools that require a JavaBean instance to operate. 937 * </p> 938 * 939 * @deprecated TODO Make private in 4.0. 940 */ 941 @Deprecated 942 public FieldUtils() { 943 // empty 944 } 945}