View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3.reflect;
19  
20  import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
21  import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
22  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertFalse;
25  import static org.junit.jupiter.api.Assertions.assertInstanceOf;
26  import static org.junit.jupiter.api.Assertions.assertNotNull;
27  import static org.junit.jupiter.api.Assertions.assertNull;
28  import static org.junit.jupiter.api.Assertions.assertThrows;
29  import static org.junit.jupiter.api.Assertions.assertTrue;
30  import static org.junit.jupiter.api.Assertions.fail;
31  import static org.junit.jupiter.api.Assumptions.assumeTrue;
32  
33  import java.lang.reflect.Constructor;
34  import java.lang.reflect.Field;
35  import java.lang.reflect.Modifier;
36  import java.util.ArrayList;
37  import java.util.Arrays;
38  import java.util.HashSet;
39  import java.util.List;
40  
41  import org.apache.commons.lang3.AbstractLangTest;
42  import org.apache.commons.lang3.ArraySorter;
43  import org.apache.commons.lang3.ArrayUtils;
44  import org.apache.commons.lang3.JavaVersion;
45  import org.apache.commons.lang3.SystemUtils;
46  import org.apache.commons.lang3.compare.ObjectToStringComparator;
47  import org.apache.commons.lang3.reflect.testbed.Ambig;
48  import org.apache.commons.lang3.reflect.testbed.Annotated;
49  import org.apache.commons.lang3.reflect.testbed.AnotherParent;
50  import org.apache.commons.lang3.reflect.testbed.Foo;
51  import org.apache.commons.lang3.reflect.testbed.PrivatelyShadowedChild;
52  import org.apache.commons.lang3.reflect.testbed.PublicChild;
53  import org.apache.commons.lang3.reflect.testbed.PubliclyShadowedChild;
54  import org.apache.commons.lang3.reflect.testbed.StaticContainer;
55  import org.apache.commons.lang3.reflect.testbed.StaticContainerChild;
56  import org.junit.jupiter.api.BeforeEach;
57  import org.junit.jupiter.api.Test;
58  
59  /**
60   * Tests FieldUtils
61   */
62  class FieldUtilsTest extends AbstractLangTest {
63  
64      interface InterfaceWithConstant {
65          int CONSTANT = 42;
66      }
67      static class MultiPathToConstant implements SubInterfaceA, SubInterfaceB {
68          // CONSTANT is reachable through both parents and through the grandparent interface
69      }
70      static class SinglePathToConstant implements SubInterfaceA {
71          // CONSTANT is reachable through the sub-interface and its super-interface
72      }
73      interface SubInterfaceA extends InterfaceWithConstant {
74          // inherits CONSTANT
75      }
76      interface SubInterfaceB extends InterfaceWithConstant {
77          // inherits CONSTANT
78      }
79      private static final String JACOCO_DATA_FIELD_NAME = "$jacocoData";
80      static final Integer I0 = Integer.valueOf(0);
81      static final Integer I1 = Integer.valueOf(1);
82      static final Double D0 = Double.valueOf(0.0);
83  
84      static final Double D1 = Double.valueOf(1.0);
85  
86      @Annotated
87      private PublicChild publicChild;
88  
89      private PubliclyShadowedChild publiclyShadowedChild;
90  
91      @Annotated
92      private PrivatelyShadowedChild privatelyShadowedChild;
93  
94      private final Class<? super PublicChild> parentClass = PublicChild.class.getSuperclass();
95  
96      /**
97       * Reads the {@code @deprecated} notice on {@link FieldUtils#removeFinalModifier(Field, boolean)}.
98       *
99       * @param field       {@link Field} to be curried into {@link FieldUtils#removeFinalModifier(Field, boolean)}.
100      * @param forceAccess {@link Boolean} to be curried into {@link FieldUtils#removeFinalModifier(Field, boolean)}.
101      */
102     private void callRemoveFinalModifierCheckForException(final Field field, final Boolean forceAccess) {
103         try {
104             FieldUtils.removeFinalModifier(field, forceAccess);
105         } catch (final UnsupportedOperationException exception) {
106             if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_12)) {
107                 assertInstanceOf(NoSuchFieldException.class, exception.getCause());
108             } else {
109                 fail("No exception should be thrown for java prior to 12.0");
110             }
111         }
112     }
113 
114     @BeforeEach
115     public void setUp() {
116         StaticContainer.reset();
117         publicChild = new PublicChild();
118         publiclyShadowedChild = new PubliclyShadowedChild();
119         privatelyShadowedChild = new PrivatelyShadowedChild();
120     }
121 
122     private Field[] sort(final Field[] fields) {
123         // Field does not implement Comparable, so we use a KISS solution here.
124         return ArraySorter.sort(fields, ObjectToStringComparator.INSTANCE);
125     }
126 
127     @Test
128     void testAmbig() {
129         assertIllegalArgumentException(() -> FieldUtils.getField(Ambig.class, "VALUE"));
130     }
131 
132     @Test
133     void testConstructor() {
134         assertNotNull(new FieldUtils());
135         final Constructor<?>[] cons = FieldUtils.class.getDeclaredConstructors();
136         assertEquals(1, cons.length);
137         assertTrue(Modifier.isPublic(cons[0].getModifiers()));
138         assertTrue(Modifier.isPublic(FieldUtils.class.getModifiers()));
139         assertFalse(Modifier.isFinal(FieldUtils.class.getModifiers()));
140     }
141 
142     @Test
143     void testGetAllFieldListsNullPointerException() {
144         assertNullPointerException(() -> FieldUtils.getAllFieldsList(null));
145     }
146 
147     @Test
148     void testGetAllFields() {
149         assertArrayEquals(new Field[0], FieldUtils.getAllFields(Object.class));
150         final Field[] fieldsNumber = sort(Number.class.getDeclaredFields());
151         assertArrayEquals(fieldsNumber, sort(FieldUtils.getAllFields(Number.class)));
152         final Field[] fieldsInteger = Integer.class.getDeclaredFields();
153         assertArrayEquals(sort(ArrayUtils.addAll(fieldsInteger, fieldsNumber)), sort(FieldUtils.getAllFields(Integer.class)));
154         final Field[] allFields = FieldUtils.getAllFields(PublicChild.class);
155         // Under Jacoco,0.8.1 and Java 10, the field count is 7.
156         int expected = 5;
157         for (final Field field : allFields) {
158             if (field.getName().equals(JACOCO_DATA_FIELD_NAME)) {
159                 expected++;
160             }
161         }
162         assertEquals(expected, allFields.length, Arrays.toString(allFields));
163     }
164 
165     @Test
166     void testGetAllFieldsList() {
167         assertEquals(0, FieldUtils.getAllFieldsList(Object.class).size());
168         final List<Field> fieldsNumber = Arrays.asList(Number.class.getDeclaredFields());
169         assertEquals(fieldsNumber, FieldUtils.getAllFieldsList(Number.class));
170         final List<Field> fieldsInteger = Arrays.asList(Integer.class.getDeclaredFields());
171         final List<Field> allFieldsInteger = new ArrayList<>(fieldsInteger);
172         allFieldsInteger.addAll(fieldsNumber);
173         assertEquals(new HashSet<>(allFieldsInteger), new HashSet<>(FieldUtils.getAllFieldsList(Integer.class)));
174         final List<Field> allFields = FieldUtils.getAllFieldsList(PublicChild.class);
175         // Under Jacoco,0.8.1 and Java 10, the field count is 7.
176         int expected = 5;
177         for (final Field field : allFields) {
178             if (field.getName().equals(JACOCO_DATA_FIELD_NAME)) {
179                 expected++;
180             }
181         }
182         assertEquals(expected, allFields.size(), allFields.toString());
183     }
184 
185     @Test
186     void testGetAllFieldsNullPointerException() {
187         assertNullPointerException(() -> FieldUtils.getAllFields(null));
188     }
189 
190     @Test
191     void testGetDeclaredField() {
192         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "VALUE"));
193         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "s"));
194         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "b"));
195         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "i"));
196         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "d"));
197         assertNull(FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "VALUE"));
198         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "s").getDeclaringClass());
199         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "b").getDeclaringClass());
200         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "i").getDeclaringClass());
201         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "d").getDeclaringClass());
202         assertNull(FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "VALUE"));
203         assertNull(FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "s"));
204         assertNull(FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "b"));
205         assertNull(FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "i"));
206         assertNull(FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "d"));
207     }
208 
209     @Test
210     void testGetDeclaredFieldAccessIllegalArgumentException1() {
211         assertIllegalArgumentException(() -> FieldUtils.getDeclaredField(PublicChild.class, null));
212     }
213 
214     @Test
215     void testGetDeclaredFieldAccessIllegalArgumentException2() {
216         assertIllegalArgumentException(() -> FieldUtils.getDeclaredField(PublicChild.class, ""));
217     }
218 
219     @Test
220     void testGetDeclaredFieldAccessIllegalArgumentException3() {
221         assertIllegalArgumentException(() -> FieldUtils.getDeclaredField(PublicChild.class, " "));
222     }
223 
224     @Test
225     void testGetDeclaredFieldAccessNullPointerException() {
226         assertNullPointerException(() -> FieldUtils.getDeclaredField(null, "none"));
227     }
228 
229     @Test
230     void testGetDeclaredFieldForceAccess() {
231         assertEquals(PublicChild.class, FieldUtils.getDeclaredField(PublicChild.class, "VALUE", true).getDeclaringClass());
232         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "s", true));
233         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "b", true));
234         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "i", true));
235         assertNull(FieldUtils.getDeclaredField(PublicChild.class, "d", true));
236         assertNull(FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "VALUE", true));
237         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "s", true).getDeclaringClass());
238         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "b", true).getDeclaringClass());
239         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "i", true).getDeclaringClass());
240         assertEquals(PubliclyShadowedChild.class, FieldUtils.getDeclaredField(PubliclyShadowedChild.class, "d", true).getDeclaringClass());
241         assertNull(FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "VALUE", true));
242         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "s", true).getDeclaringClass());
243         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "b", true).getDeclaringClass());
244         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "i", true).getDeclaringClass());
245         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getDeclaredField(PrivatelyShadowedChild.class, "d", true).getDeclaringClass());
246     }
247 
248     @Test
249     void testGetDeclaredFieldForceAccessIllegalArgumentException1() {
250         assertIllegalArgumentException(() -> FieldUtils.getDeclaredField(PublicChild.class, null, true));
251     }
252 
253     @Test
254     void testGetDeclaredFieldForceAccessIllegalArgumentException2() {
255         assertIllegalArgumentException(() -> FieldUtils.getDeclaredField(PublicChild.class, "", true));
256     }
257 
258     @Test
259     void testGetDeclaredFieldForceAccessIllegalArgumentException3() {
260         assertIllegalArgumentException(() -> FieldUtils.getDeclaredField(PublicChild.class, " ", true));
261     }
262 
263     @Test
264     void testGetDeclaredFieldForceAccessNullPointerException() {
265         assertNullPointerException(() -> FieldUtils.getDeclaredField(null, "none", true));
266     }
267 
268     @Test
269     void testGetField() {
270         assertEquals(Foo.class, FieldUtils.getField(PublicChild.class, "VALUE").getDeclaringClass());
271         assertEquals(parentClass, FieldUtils.getField(PublicChild.class, "s").getDeclaringClass());
272         assertNull(FieldUtils.getField(PublicChild.class, "b"));
273         assertNull(FieldUtils.getField(PublicChild.class, "i"));
274         assertNull(FieldUtils.getField(PublicChild.class, "d"));
275         assertEquals(Foo.class, FieldUtils.getField(PubliclyShadowedChild.class, "VALUE").getDeclaringClass());
276         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "s").getDeclaringClass());
277         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "b").getDeclaringClass());
278         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "i").getDeclaringClass());
279         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "d").getDeclaringClass());
280         assertEquals(Foo.class, FieldUtils.getField(PrivatelyShadowedChild.class, "VALUE").getDeclaringClass());
281         assertEquals(parentClass, FieldUtils.getField(PrivatelyShadowedChild.class, "s").getDeclaringClass());
282         assertNull(FieldUtils.getField(PrivatelyShadowedChild.class, "b"));
283         assertNull(FieldUtils.getField(PrivatelyShadowedChild.class, "i"));
284         assertNull(FieldUtils.getField(PrivatelyShadowedChild.class, "d"));
285     }
286 
287     @Test
288     void testGetFieldForceAccess() {
289         assertEquals(PublicChild.class, FieldUtils.getField(PublicChild.class, "VALUE", true).getDeclaringClass());
290         assertEquals(parentClass, FieldUtils.getField(PublicChild.class, "s", true).getDeclaringClass());
291         assertEquals(parentClass, FieldUtils.getField(PublicChild.class, "b", true).getDeclaringClass());
292         assertEquals(parentClass, FieldUtils.getField(PublicChild.class, "i", true).getDeclaringClass());
293         assertEquals(parentClass, FieldUtils.getField(PublicChild.class, "d", true).getDeclaringClass());
294         assertEquals(Foo.class, FieldUtils.getField(PubliclyShadowedChild.class, "VALUE", true).getDeclaringClass());
295         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "s", true).getDeclaringClass());
296         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "b", true).getDeclaringClass());
297         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "i", true).getDeclaringClass());
298         assertEquals(PubliclyShadowedChild.class, FieldUtils.getField(PubliclyShadowedChild.class, "d", true).getDeclaringClass());
299         assertEquals(Foo.class, FieldUtils.getField(PrivatelyShadowedChild.class, "VALUE", true).getDeclaringClass());
300         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getField(PrivatelyShadowedChild.class, "s", true).getDeclaringClass());
301         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getField(PrivatelyShadowedChild.class, "b", true).getDeclaringClass());
302         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getField(PrivatelyShadowedChild.class, "i", true).getDeclaringClass());
303         assertEquals(PrivatelyShadowedChild.class, FieldUtils.getField(PrivatelyShadowedChild.class, "d", true).getDeclaringClass());
304     }
305 
306     @Test
307     void testGetFieldForceAccessIllegalArgumentException1() {
308         assertIllegalArgumentException(() -> FieldUtils.getField(PublicChild.class, null, true));
309     }
310 
311     @Test
312     void testGetFieldForceAccessIllegalArgumentException2() {
313         assertIllegalArgumentException(() -> FieldUtils.getField(PublicChild.class, "", true));
314     }
315 
316     @Test
317     void testGetFieldForceAccessIllegalArgumentException3() {
318         assertIllegalArgumentException(() -> FieldUtils.getField(PublicChild.class, " ", true));
319     }
320 
321     @Test
322     void testGetFieldForceAccessNullPointerException() {
323         assertNullPointerException(() -> FieldUtils.getField(null, "none", true));
324     }
325 
326     @Test
327     void testGetFieldIllegalArgumentException1() {
328         assertIllegalArgumentException(() -> FieldUtils.getField(PublicChild.class, null));
329     }
330 
331     @Test
332     void testGetFieldIllegalArgumentException2() {
333         assertIllegalArgumentException(() -> FieldUtils.getField(PublicChild.class, ""));
334     }
335 
336     @Test
337     void testGetFieldIllegalArgumentException3() {
338         assertIllegalArgumentException(() -> FieldUtils.getField(PublicChild.class, " "));
339     }
340 
341     @Test
342     void testGetFieldInheritedThroughMultipleInterfacePaths() {
343         // A field reached through more than one interface path resolves to the same Field, so it is not ambiguous.
344         assertEquals(InterfaceWithConstant.class, FieldUtils.getField(SinglePathToConstant.class, "CONSTANT").getDeclaringClass());
345         assertEquals(InterfaceWithConstant.class, FieldUtils.getField(MultiPathToConstant.class, "CONSTANT").getDeclaringClass());
346         // A genuine clash of two different fields on unrelated interfaces is still ambiguous.
347         assertIllegalArgumentException(() -> FieldUtils.getField(Ambig.class, "VALUE"));
348     }
349 
350     @Test
351     void testGetFieldNullPointerException() {
352         assertNullPointerException(() -> FieldUtils.getField(null, "none"));
353     }
354 
355     @Test
356     void testGetFieldsListWithAnnotation() throws NoSuchFieldException {
357         assertEquals(0, FieldUtils.getFieldsListWithAnnotation(Object.class, Annotated.class).size());
358         final List<Field> annotatedFields = Arrays.asList(FieldUtilsTest.class.getDeclaredField("publicChild"),
359                 FieldUtilsTest.class.getDeclaredField("privatelyShadowedChild"));
360         final List<Field> fieldUtilsTestAnnotatedFields = FieldUtils.getFieldsListWithAnnotation(FieldUtilsTest.class, Annotated.class);
361         assertEquals(annotatedFields.size(), fieldUtilsTestAnnotatedFields.size());
362         assertTrue(fieldUtilsTestAnnotatedFields.contains(annotatedFields.get(0)));
363         assertTrue(fieldUtilsTestAnnotatedFields.contains(annotatedFields.get(1)));
364     }
365 
366     @Test
367     void testGetFieldsListWithAnnotationNullPointerException() {
368         assertNullPointerException(() -> FieldUtils.getFieldsListWithAnnotation(FieldUtilsTest.class, null));
369     }
370 
371     @Test
372     void testGetFieldsListWithAnnotationNullPointerException2() {
373         assertNullPointerException(() -> FieldUtils.getFieldsListWithAnnotation(null, Annotated.class));
374     }
375 
376     @Test
377     void testGetFieldsListWithAnnotationNullPointerException3() {
378         assertNullPointerException(() -> FieldUtils.getFieldsListWithAnnotation(null, null));
379     }
380 
381     @Test
382     void testGetFieldsWithAnnotation() throws NoSuchFieldException {
383         assertArrayEquals(new Field[0], FieldUtils.getFieldsWithAnnotation(Object.class, Annotated.class));
384         final Field[] annotatedFields = sort(
385                 new Field[] { FieldUtilsTest.class.getDeclaredField("publicChild"), FieldUtilsTest.class.getDeclaredField("privatelyShadowedChild") });
386         assertArrayEquals(annotatedFields, sort(FieldUtils.getFieldsWithAnnotation(FieldUtilsTest.class, Annotated.class)));
387     }
388 
389     @Test
390     void testGetFieldsWithAnnotationNullPointerException1() {
391         assertNullPointerException(() -> FieldUtils.getFieldsWithAnnotation(FieldUtilsTest.class, null));
392     }
393 
394     @Test
395     void testGetFieldsWithAnnotationNullPointerException2() {
396         assertNullPointerException(() -> FieldUtils.getFieldsWithAnnotation(null, Annotated.class));
397     }
398 
399     @Test
400     void testGetFieldsWithAnnotationNullPointerException3() {
401         assertNullPointerException(() -> FieldUtils.getFieldsWithAnnotation(null, null));
402     }
403 
404     @Test
405     void testReadDeclaredNamedField() throws Exception {
406         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, null),
407                 "a null field name should cause an IllegalArgumentException");
408         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, ""),
409                 "an empty field name should cause an IllegalArgumentException");
410         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, " "),
411                 "a blank field name should cause an IllegalArgumentException");
412         assertNullPointerException(() -> FieldUtils.readDeclaredField(null, "none"), "a null target should cause an NullPointerException");
413         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "s"));
414         assertEquals("ss", FieldUtils.readDeclaredField(publiclyShadowedChild, "s"));
415         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(privatelyShadowedChild, "s"));
416         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "b"));
417         assertEquals(Boolean.TRUE, FieldUtils.readDeclaredField(publiclyShadowedChild, "b"));
418         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(privatelyShadowedChild, "b"));
419         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "i"));
420         assertEquals(I1, FieldUtils.readDeclaredField(publiclyShadowedChild, "i"));
421         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(privatelyShadowedChild, "i"));
422         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "d"));
423         assertEquals(D1, FieldUtils.readDeclaredField(publiclyShadowedChild, "d"));
424         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(privatelyShadowedChild, "d"));
425     }
426 
427     @Test
428     void testReadDeclaredNamedFieldForceAccess() throws Exception {
429         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, null, true),
430                 "a null field name should cause an IllegalArgumentException");
431         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "", true),
432                 "an empty field name should cause an IllegalArgumentException");
433         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, " ", true),
434                 "a blank field name should cause an IllegalArgumentException");
435         assertNullPointerException(() -> FieldUtils.readDeclaredField(null, "none", true), "a null target should cause an NullPointerException");
436         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "s", true));
437         assertEquals("ss", FieldUtils.readDeclaredField(publiclyShadowedChild, "s", true));
438         assertEquals("ss", FieldUtils.readDeclaredField(privatelyShadowedChild, "s", true));
439         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "b", true));
440         assertEquals(Boolean.TRUE, FieldUtils.readDeclaredField(publiclyShadowedChild, "b", true));
441         assertEquals(Boolean.TRUE, FieldUtils.readDeclaredField(privatelyShadowedChild, "b", true));
442         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "i", true));
443         assertEquals(I1, FieldUtils.readDeclaredField(publiclyShadowedChild, "i", true));
444         assertEquals(I1, FieldUtils.readDeclaredField(privatelyShadowedChild, "i", true));
445         assertIllegalArgumentException(() -> FieldUtils.readDeclaredField(publicChild, "d", true));
446         assertEquals(D1, FieldUtils.readDeclaredField(publiclyShadowedChild, "d", true));
447         assertEquals(D1, FieldUtils.readDeclaredField(privatelyShadowedChild, "d", true));
448     }
449 
450     @Test
451     void testReadDeclaredNamedStaticField() throws Exception {
452         assertNullPointerException(() -> FieldUtils.readDeclaredStaticField(AnotherParent.class, "doesNotExist"));
453         assertEquals(Foo.VALUE, FieldUtils.readDeclaredStaticField(Foo.class, "VALUE"));
454         assertNullPointerException(() -> FieldUtils.readDeclaredField(null, "VALUE"));
455         assertNullPointerException(() -> FieldUtils.readDeclaredStaticField(PublicChild.class, "VALUE"));
456         assertNullPointerException(() -> FieldUtils.readDeclaredStaticField(PubliclyShadowedChild.class, "VALUE"));
457         assertNullPointerException(() -> FieldUtils.readDeclaredStaticField(PrivatelyShadowedChild.class, "VALUE"));
458         assertIllegalArgumentException(() -> FieldUtils.readDeclaredStaticField(PublicChild.class, null));
459         assertIllegalArgumentException(() -> FieldUtils.readDeclaredStaticField(PublicChild.class, ""));
460         assertIllegalArgumentException(() -> FieldUtils.readDeclaredStaticField(PublicChild.class, " "));
461     }
462 
463     @Test
464     void testReadDeclaredNamedStaticFieldForceAccess() throws Exception {
465         assertEquals(Foo.VALUE, FieldUtils.readDeclaredStaticField(Foo.class, "VALUE", true));
466         assertEquals("child", FieldUtils.readDeclaredStaticField(PublicChild.class, "VALUE", true));
467         assertNullPointerException(() -> FieldUtils.readDeclaredStaticField(PubliclyShadowedChild.class, "VALUE", true));
468         assertNullPointerException(() -> FieldUtils.readDeclaredStaticField(PrivatelyShadowedChild.class, "VALUE", true));
469         assertIllegalArgumentException(() -> FieldUtils.readDeclaredStaticField(PrivatelyShadowedChild.class, null, true));
470         assertIllegalArgumentException(() -> FieldUtils.readDeclaredStaticField(PrivatelyShadowedChild.class, "", true));
471         assertIllegalArgumentException(() -> FieldUtils.readDeclaredStaticField(PrivatelyShadowedChild.class, " ", true));
472     }
473 
474     @Test
475     void testReadField() throws Exception {
476         final Field parentS = FieldUtils.getDeclaredField(parentClass, "s");
477         assertEquals("s", FieldUtils.readField(parentS, publicChild));
478         assertEquals("s", FieldUtils.readField(parentS, publiclyShadowedChild));
479         assertEquals("s", FieldUtils.readField(parentS, privatelyShadowedChild));
480         final Field parentB = FieldUtils.getDeclaredField(parentClass, "b", true);
481         assertEquals(Boolean.FALSE, FieldUtils.readField(parentB, publicChild));
482         assertEquals(Boolean.FALSE, FieldUtils.readField(parentB, publiclyShadowedChild));
483         assertEquals(Boolean.FALSE, FieldUtils.readField(parentB, privatelyShadowedChild));
484         final Field parentI = FieldUtils.getDeclaredField(parentClass, "i", true);
485         assertEquals(I0, FieldUtils.readField(parentI, publicChild));
486         assertEquals(I0, FieldUtils.readField(parentI, publiclyShadowedChild));
487         assertEquals(I0, FieldUtils.readField(parentI, privatelyShadowedChild));
488         final Field parentD = FieldUtils.getDeclaredField(parentClass, "d", true);
489         assertEquals(D0, FieldUtils.readField(parentD, publicChild));
490         assertEquals(D0, FieldUtils.readField(parentD, publiclyShadowedChild));
491         assertEquals(D0, FieldUtils.readField(parentD, privatelyShadowedChild));
492         assertNullPointerException(() -> FieldUtils.readField(null, publicChild), "a null field should cause an NullPointerException");
493     }
494 
495     @Test
496     void testReadFieldForceAccess() throws Exception {
497         final Field parentS = FieldUtils.getDeclaredField(parentClass, "s");
498         parentS.setAccessible(false);
499         assertEquals("s", FieldUtils.readField(parentS, publicChild, true));
500         assertEquals("s", FieldUtils.readField(parentS, publiclyShadowedChild, true));
501         assertEquals("s", FieldUtils.readField(parentS, privatelyShadowedChild, true));
502         final Field parentB = FieldUtils.getDeclaredField(parentClass, "b", true);
503         parentB.setAccessible(false);
504         assertEquals(Boolean.FALSE, FieldUtils.readField(parentB, publicChild, true));
505         assertEquals(Boolean.FALSE, FieldUtils.readField(parentB, publiclyShadowedChild, true));
506         assertEquals(Boolean.FALSE, FieldUtils.readField(parentB, privatelyShadowedChild, true));
507         final Field parentI = FieldUtils.getDeclaredField(parentClass, "i", true);
508         parentI.setAccessible(false);
509         assertEquals(I0, FieldUtils.readField(parentI, publicChild, true));
510         assertEquals(I0, FieldUtils.readField(parentI, publiclyShadowedChild, true));
511         assertEquals(I0, FieldUtils.readField(parentI, privatelyShadowedChild, true));
512         final Field parentD = FieldUtils.getDeclaredField(parentClass, "d", true);
513         parentD.setAccessible(false);
514         assertEquals(D0, FieldUtils.readField(parentD, publicChild, true));
515         assertEquals(D0, FieldUtils.readField(parentD, publiclyShadowedChild, true));
516         assertEquals(D0, FieldUtils.readField(parentD, privatelyShadowedChild, true));
517         assertNullPointerException(() -> FieldUtils.readField(null, publicChild, true), "a null field should cause an NullPointerException");
518     }
519 
520     @Test
521     void testReadNamedField() throws Exception {
522         assertEquals("s", FieldUtils.readField(publicChild, "s"));
523         assertEquals("ss", FieldUtils.readField(publiclyShadowedChild, "s"));
524         assertEquals("s", FieldUtils.readField(privatelyShadowedChild, "s"));
525         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, null),
526                 "a null field name should cause an IllegalArgumentException");
527         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, ""),
528                 "an empty field name should cause an IllegalArgumentException");
529         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, " "),
530                 "a blank field name should cause an IllegalArgumentException");
531         assertNullPointerException(() -> FieldUtils.readField((Object) null, "none"), "a null target should cause an NullPointerException");
532         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, "b"));
533         assertEquals(Boolean.TRUE, FieldUtils.readField(publiclyShadowedChild, "b"));
534         assertIllegalArgumentException(() -> FieldUtils.readField(privatelyShadowedChild, "b"));
535         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, "i"));
536         assertEquals(I1, FieldUtils.readField(publiclyShadowedChild, "i"));
537         assertIllegalArgumentException(() -> FieldUtils.readField(privatelyShadowedChild, "i"));
538         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, "d"));
539         assertEquals(D1, FieldUtils.readField(publiclyShadowedChild, "d"));
540         assertIllegalArgumentException(() -> FieldUtils.readField(privatelyShadowedChild, "d"));
541     }
542 
543     @Test
544     void testReadNamedFieldForceAccess() throws Exception {
545         assertEquals("s", FieldUtils.readField(publicChild, "s", true));
546         assertEquals("ss", FieldUtils.readField(publiclyShadowedChild, "s", true));
547         assertEquals("ss", FieldUtils.readField(privatelyShadowedChild, "s", true));
548         assertEquals(Boolean.FALSE, FieldUtils.readField(publicChild, "b", true));
549         assertEquals(Boolean.TRUE, FieldUtils.readField(publiclyShadowedChild, "b", true));
550         assertEquals(Boolean.TRUE, FieldUtils.readField(privatelyShadowedChild, "b", true));
551         assertEquals(I0, FieldUtils.readField(publicChild, "i", true));
552         assertEquals(I1, FieldUtils.readField(publiclyShadowedChild, "i", true));
553         assertEquals(I1, FieldUtils.readField(privatelyShadowedChild, "i", true));
554         assertEquals(D0, FieldUtils.readField(publicChild, "d", true));
555         assertEquals(D1, FieldUtils.readField(publiclyShadowedChild, "d", true));
556         assertEquals(D1, FieldUtils.readField(privatelyShadowedChild, "d", true));
557         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, null, true),
558                 "a null field name should cause an IllegalArgumentException");
559         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, "", true),
560                 "an empty field name should cause an IllegalArgumentException");
561         assertIllegalArgumentException(() -> FieldUtils.readField(publicChild, " ", true),
562                 "a blank field name should cause an IllegalArgumentException");
563         assertNullPointerException(() -> FieldUtils.readField((Object) null, "none", true), "a null target should cause an NullPointerException");
564     }
565 
566     @Test
567     void testReadNamedStaticField() throws Exception {
568         assertEquals(Foo.VALUE, FieldUtils.readStaticField(Foo.class, "VALUE"));
569         assertEquals(Foo.VALUE, FieldUtils.readStaticField(PubliclyShadowedChild.class, "VALUE"));
570         assertEquals(Foo.VALUE, FieldUtils.readStaticField(PrivatelyShadowedChild.class, "VALUE"));
571         assertEquals(Foo.VALUE, FieldUtils.readStaticField(PublicChild.class, "VALUE"));
572         assertNullPointerException(() -> FieldUtils.readStaticField(null, "none"), "null class should cause an NullPointerException");
573         assertIllegalArgumentException(() -> FieldUtils.readStaticField(Foo.class, null),
574                 "null field name should cause an IllegalArgumentException");
575         assertIllegalArgumentException(() -> FieldUtils.readStaticField(Foo.class, ""),
576                 "empty field name should cause an IllegalArgumentException");
577         assertIllegalArgumentException(() -> FieldUtils.readStaticField(Foo.class, " "),
578                 "blank field name should cause an IllegalArgumentException");
579         assertNullPointerException(() -> FieldUtils.readStaticField(Foo.class, "does_not_exist"),
580                 "a field that doesn't exist should cause an NullPointerException");
581         assertIllegalArgumentException(() -> FieldUtils.readStaticField(PublicChild.class, "s"),
582                 "non-static field should cause an IllegalArgumentException");
583     }
584 
585     @Test
586     void testReadNamedStaticFieldForceAccess() throws Exception {
587         assertEquals(Foo.VALUE, FieldUtils.readStaticField(Foo.class, "VALUE", true));
588         assertEquals(Foo.VALUE, FieldUtils.readStaticField(PubliclyShadowedChild.class, "VALUE", true));
589         assertEquals(Foo.VALUE, FieldUtils.readStaticField(PrivatelyShadowedChild.class, "VALUE", true));
590         assertEquals("child", FieldUtils.readStaticField(PublicChild.class, "VALUE", true));
591         assertNullPointerException(() -> FieldUtils.readStaticField(null, "none", true), "null class should cause an NullPointerException");
592         assertIllegalArgumentException(() -> FieldUtils.readStaticField(Foo.class, null, true),
593                 "null field name should cause an IllegalArgumentException");
594         assertIllegalArgumentException(() -> FieldUtils.readStaticField(Foo.class, "", true),
595                 "empty field name should cause an IllegalArgumentException");
596         assertIllegalArgumentException(() -> FieldUtils.readStaticField(Foo.class, " ", true),
597                 "blank field name should cause an IllegalArgumentException");
598         assertNullPointerException(() -> FieldUtils.readStaticField(Foo.class, "does_not_exist", true),
599                 "a field that doesn't exist should cause an NullPointerException");
600         assertIllegalArgumentException(() -> FieldUtils.readStaticField(PublicChild.class, "s", false),
601                 "non-static field should cause an IllegalArgumentException");
602     }
603 
604     @Test
605     void testReadStaticField() throws Exception {
606         assertEquals(Foo.VALUE, FieldUtils.readStaticField(FieldUtils.getField(Foo.class, "VALUE")));
607     }
608 
609     @Test
610     void testReadStaticFieldForceAccess() throws Exception {
611         assertEquals(Foo.VALUE, FieldUtils.readStaticField(FieldUtils.getField(Foo.class, "VALUE")));
612         assertEquals(Foo.VALUE, FieldUtils.readStaticField(FieldUtils.getField(PublicChild.class, "VALUE")));
613     }
614 
615     @Test
616     void testReadStaticFieldForceAccessIllegalArgumentException() {
617         final Field nonStaticField = FieldUtils.getField(PublicChild.class, "s", true);
618         assumeTrue(nonStaticField != null);
619         assertIllegalArgumentException(() -> FieldUtils.readStaticField(nonStaticField, true));
620     }
621 
622     @Test
623     void testReadStaticFieldForceAccessNullPointerException() {
624         assertNullPointerException(() -> FieldUtils.readStaticField(null, true));
625     }
626 
627     @Test
628     void testReadStaticFieldIllegalArgumentException() throws Exception {
629         assertEquals(Foo.VALUE, FieldUtils.readStaticField(FieldUtils.getField(Foo.class, "VALUE")));
630         final Field nonStaticField = FieldUtils.getField(PublicChild.class, "s");
631         assumeTrue(nonStaticField != null);
632         assertIllegalArgumentException(() -> FieldUtils.readStaticField(nonStaticField));
633     }
634 
635     @Test
636     void testReadStaticFieldNullPointerException() {
637         assertNullPointerException(() -> FieldUtils.readStaticField(null));
638     }
639 
640     @Test
641     void testRemoveFinalModifier() throws Exception {
642         final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
643         assertFalse(field.isAccessible());
644         assertTrue(Modifier.isFinal(field.getModifiers()));
645         callRemoveFinalModifierCheckForException(field, true);
646         if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
647             assertFalse(Modifier.isFinal(field.getModifiers()));
648             assertFalse(field.isAccessible());
649         }
650     }
651 
652     @Test
653     void testRemoveFinalModifierAccessNotNeeded() throws Exception {
654         final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PACKAGE");
655         assertFalse(field.isAccessible());
656         assertTrue(Modifier.isFinal(field.getModifiers()));
657         callRemoveFinalModifierCheckForException(field, false);
658         if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
659             assertTrue(Modifier.isFinal(field.getModifiers()));
660             assertFalse(field.isAccessible());
661         }
662     }
663 
664     @Test
665     void testRemoveFinalModifierNullPointerException() {
666         assertNullPointerException(() -> FieldUtils.removeFinalModifier(null));
667     }
668 
669     @Test
670     void testRemoveFinalModifierWithAccess() throws Exception {
671         final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
672         assertFalse(field.isAccessible());
673         assertTrue(Modifier.isFinal(field.getModifiers()));
674         callRemoveFinalModifierCheckForException(field, true);
675         if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
676             assertFalse(Modifier.isFinal(field.getModifiers()));
677             assertFalse(field.isAccessible());
678         }
679     }
680 
681     @Test
682     void testRemoveFinalModifierWithAccessNullPointerException() {
683         assertNullPointerException(() -> FieldUtils.removeFinalModifier(null, true));
684     }
685 
686     @Test
687     void testRemoveFinalModifierWithoutAccess() throws Exception {
688         final Field field = StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE_2");
689         assertFalse(field.isAccessible());
690         assertTrue(Modifier.isFinal(field.getModifiers()));
691         callRemoveFinalModifierCheckForException(field, false);
692         if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_11)) {
693             assertTrue(Modifier.isFinal(field.getModifiers()));
694             assertFalse(field.isAccessible());
695         }
696     }
697 
698     @Test
699     void testWriteDeclaredNamedField() throws Exception {
700         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "s", "S"));
701         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "b", Boolean.TRUE));
702         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "i", Integer.valueOf(1)));
703         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "d", Double.valueOf(1.0)));
704         FieldUtils.writeDeclaredField(publiclyShadowedChild, "s", "S");
705         assertEquals("S", FieldUtils.readDeclaredField(publiclyShadowedChild, "s"));
706         FieldUtils.writeDeclaredField(publiclyShadowedChild, "b", Boolean.FALSE);
707         assertEquals(Boolean.FALSE, FieldUtils.readDeclaredField(publiclyShadowedChild, "b"));
708         FieldUtils.writeDeclaredField(publiclyShadowedChild, "i", Integer.valueOf(0));
709         assertEquals(Integer.valueOf(0), FieldUtils.readDeclaredField(publiclyShadowedChild, "i"));
710         FieldUtils.writeDeclaredField(publiclyShadowedChild, "d", Double.valueOf(0.0));
711         assertEquals(Double.valueOf(0.0), FieldUtils.readDeclaredField(publiclyShadowedChild, "d"));
712         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(privatelyShadowedChild, "s", "S"));
713         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(privatelyShadowedChild, "b", Boolean.TRUE));
714         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(privatelyShadowedChild, "i", Integer.valueOf(1)));
715         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(privatelyShadowedChild, "d", Double.valueOf(1.0)));
716         assertNullPointerException(() -> FieldUtils.writeDeclaredField(null, "s", "S"));
717         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "null", "S"));
718         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "", "S"));
719         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, " ", "S"));
720     }
721 
722     @Test
723     void testWriteDeclaredNamedFieldForceAccess() throws Exception {
724         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "s", "S", true));
725         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "b", Boolean.TRUE, true));
726         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "i", Integer.valueOf(1), true));
727         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "d", Double.valueOf(1.0), true));
728         FieldUtils.writeDeclaredField(publiclyShadowedChild, "s", "S", true);
729         assertEquals("S", FieldUtils.readDeclaredField(publiclyShadowedChild, "s", true));
730         FieldUtils.writeDeclaredField(publiclyShadowedChild, "b", Boolean.FALSE, true);
731         assertEquals(Boolean.FALSE, FieldUtils.readDeclaredField(publiclyShadowedChild, "b", true));
732         FieldUtils.writeDeclaredField(publiclyShadowedChild, "i", Integer.valueOf(0), true);
733         assertEquals(Integer.valueOf(0), FieldUtils.readDeclaredField(publiclyShadowedChild, "i", true));
734         FieldUtils.writeDeclaredField(publiclyShadowedChild, "d", Double.valueOf(0.0), true);
735         assertEquals(Double.valueOf(0.0), FieldUtils.readDeclaredField(publiclyShadowedChild, "d", true));
736         FieldUtils.writeDeclaredField(privatelyShadowedChild, "s", "S", true);
737         assertEquals("S", FieldUtils.readDeclaredField(privatelyShadowedChild, "s", true));
738         FieldUtils.writeDeclaredField(privatelyShadowedChild, "b", Boolean.FALSE, true);
739         assertEquals(Boolean.FALSE, FieldUtils.readDeclaredField(privatelyShadowedChild, "b", true));
740         FieldUtils.writeDeclaredField(privatelyShadowedChild, "i", Integer.valueOf(0), true);
741         assertEquals(Integer.valueOf(0), FieldUtils.readDeclaredField(privatelyShadowedChild, "i", true));
742         FieldUtils.writeDeclaredField(privatelyShadowedChild, "d", Double.valueOf(0.0), true);
743         assertEquals(Double.valueOf(0.0), FieldUtils.readDeclaredField(privatelyShadowedChild, "d", true));
744         assertNullPointerException(() -> FieldUtils.writeDeclaredField(null, "s", "S", true));
745         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "null", "S", true));
746         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, "", "S", true));
747         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredField(publicChild, " ", "S", true));
748     }
749 
750     @Test
751     void testWriteDeclaredNamedStaticField() throws Exception {
752         FieldUtils.writeStaticField(StaticContainer.class, "mutablePublic", "new");
753         assertEquals("new", StaticContainer.mutablePublic);
754         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutableProtected", "new"));
755         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutablePackage", "new"));
756         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutablePrivate", "new"));
757         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PUBLIC", "new"));
758         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PROTECTED", "new"));
759         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PACKAGE", "new"));
760         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PRIVATE", "new"));
761         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(null, "mutablePublic", "new"));
762         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, null, "new"));
763         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "", "new"));
764         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, " ", "new"));
765     }
766 
767     @Test
768     void testWriteDeclaredNamedStaticFieldForceAccess() throws Exception {
769         FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutablePublic", "new", true);
770         assertEquals("new", StaticContainer.mutablePublic);
771         FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutableProtected", "new", true);
772         assertEquals("new", StaticContainer.getMutableProtected());
773         FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutablePackage", "new", true);
774         assertEquals("new", StaticContainer.getMutablePackage());
775         FieldUtils.writeDeclaredStaticField(StaticContainer.class, "mutablePrivate", "new", true);
776         assertEquals("new", StaticContainer.getMutablePrivate());
777         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PUBLIC", "new", true));
778         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PROTECTED", "new", true));
779         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PACKAGE", "new", true));
780         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "IMMUTABLE_PRIVATE", "new", true));
781         assertNullPointerException(() -> FieldUtils.writeDeclaredStaticField(null, "mutablePublic", "new", true));
782         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, null, "new", true));
783         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, "", "new", true));
784         assertIllegalArgumentException(() -> FieldUtils.writeDeclaredStaticField(StaticContainer.class, " ", "new", true));
785     }
786 
787     @Test
788     void testWriteField() throws Exception {
789         final Field field = parentClass.getDeclaredField("s");
790         FieldUtils.writeField(field, publicChild, "S");
791         assertEquals("S", field.get(publicChild));
792         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeField(parentClass.getDeclaredField("b"), publicChild, Boolean.TRUE));
793         assertThrows(IllegalAccessException.class,
794                 () -> FieldUtils.writeField(parentClass.getDeclaredField("i"), publicChild, Integer.valueOf(Integer.MAX_VALUE)));
795         assertThrows(IllegalAccessException.class,
796                 () -> FieldUtils.writeField(parentClass.getDeclaredField("d"), publicChild, Double.valueOf(Double.MAX_VALUE)));
797         assertNullPointerException(() -> FieldUtils.writeField(null, publicChild, "S"));
798     }
799 
800     @Test
801     void testWriteFieldForceAccess() throws Exception {
802         Field field = parentClass.getDeclaredField("s");
803         FieldUtils.writeField(field, publicChild, "S", true);
804         assertEquals("S", field.get(publicChild));
805         field = parentClass.getDeclaredField("b");
806         FieldUtils.writeField(field, publicChild, Boolean.TRUE, true);
807         assertEquals(Boolean.TRUE, field.get(publicChild));
808         field = parentClass.getDeclaredField("i");
809         FieldUtils.writeField(field, publicChild, Integer.valueOf(Integer.MAX_VALUE), true);
810         assertEquals(Integer.valueOf(Integer.MAX_VALUE), field.get(publicChild));
811         field = parentClass.getDeclaredField("d");
812         FieldUtils.writeField(field, publicChild, Double.valueOf(Double.MAX_VALUE), true);
813         assertEquals(Double.valueOf(Double.MAX_VALUE), field.get(publicChild));
814         assertNullPointerException(() -> FieldUtils.writeField(null, publicChild, "S", true));
815     }
816 
817     @Test
818     void testWriteNamedField() throws Exception {
819         FieldUtils.writeField(publicChild, "s", "S");
820         assertEquals("S", FieldUtils.readField(publicChild, "s"));
821         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, "b", Boolean.TRUE));
822         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, "i", Integer.valueOf(1)));
823         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, "d", Double.valueOf(1.0)));
824         FieldUtils.writeField(publiclyShadowedChild, "s", "S");
825         assertEquals("S", FieldUtils.readField(publiclyShadowedChild, "s"));
826         FieldUtils.writeField(publiclyShadowedChild, "b", Boolean.FALSE);
827         assertEquals(Boolean.FALSE, FieldUtils.readField(publiclyShadowedChild, "b"));
828         FieldUtils.writeField(publiclyShadowedChild, "i", Integer.valueOf(0));
829         assertEquals(Integer.valueOf(0), FieldUtils.readField(publiclyShadowedChild, "i"));
830         FieldUtils.writeField(publiclyShadowedChild, "d", Double.valueOf(0.0));
831         assertEquals(Double.valueOf(0.0), FieldUtils.readField(publiclyShadowedChild, "d"));
832         FieldUtils.writeField(privatelyShadowedChild, "s", "S");
833         assertEquals("S", FieldUtils.readField(privatelyShadowedChild, "s"));
834         assertIllegalArgumentException(() -> FieldUtils.writeField(privatelyShadowedChild, "b", Boolean.TRUE));
835         assertIllegalArgumentException(() -> FieldUtils.writeField(privatelyShadowedChild, "i", Integer.valueOf(1)));
836         assertIllegalArgumentException(() -> FieldUtils.writeField(privatelyShadowedChild, "d", Double.valueOf(1.0)));
837         assertNullPointerException(() -> FieldUtils.writeField((Object) null, "s", "s"));
838         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, null, "s"));
839         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, "", "s"));
840         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, " ", "s"));
841     }
842 
843     @Test
844     void testWriteNamedFieldForceAccess() throws Exception {
845         FieldUtils.writeField(publicChild, "s", "S", true);
846         assertEquals("S", FieldUtils.readField(publicChild, "s", true));
847         FieldUtils.writeField(publicChild, "b", Boolean.TRUE, true);
848         assertEquals(Boolean.TRUE, FieldUtils.readField(publicChild, "b", true));
849         FieldUtils.writeField(publicChild, "i", Integer.valueOf(1), true);
850         assertEquals(Integer.valueOf(1), FieldUtils.readField(publicChild, "i", true));
851         FieldUtils.writeField(publicChild, "d", Double.valueOf(1.0), true);
852         assertEquals(Double.valueOf(1.0), FieldUtils.readField(publicChild, "d", true));
853         FieldUtils.writeField(publiclyShadowedChild, "s", "S", true);
854         assertEquals("S", FieldUtils.readField(publiclyShadowedChild, "s", true));
855         FieldUtils.writeField(publiclyShadowedChild, "b", Boolean.FALSE, true);
856         assertEquals(Boolean.FALSE, FieldUtils.readField(publiclyShadowedChild, "b", true));
857         FieldUtils.writeField(publiclyShadowedChild, "i", Integer.valueOf(0), true);
858         assertEquals(Integer.valueOf(0), FieldUtils.readField(publiclyShadowedChild, "i", true));
859         FieldUtils.writeField(publiclyShadowedChild, "d", Double.valueOf(0.0), true);
860         assertEquals(Double.valueOf(0.0), FieldUtils.readField(publiclyShadowedChild, "d", true));
861         FieldUtils.writeField(privatelyShadowedChild, "s", "S", true);
862         assertEquals("S", FieldUtils.readField(privatelyShadowedChild, "s", true));
863         FieldUtils.writeField(privatelyShadowedChild, "b", Boolean.FALSE, true);
864         assertEquals(Boolean.FALSE, FieldUtils.readField(privatelyShadowedChild, "b", true));
865         FieldUtils.writeField(privatelyShadowedChild, "i", Integer.valueOf(0), true);
866         assertEquals(Integer.valueOf(0), FieldUtils.readField(privatelyShadowedChild, "i", true));
867         FieldUtils.writeField(privatelyShadowedChild, "d", Double.valueOf(0.0), true);
868         assertEquals(Double.valueOf(0.0), FieldUtils.readField(privatelyShadowedChild, "d", true));
869         assertNullPointerException(() -> FieldUtils.writeField((Object) null, "s", "s", true));
870         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, null, "s", true));
871         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, "", "s", true));
872         assertIllegalArgumentException(() -> FieldUtils.writeField(publicChild, " ", "s", true));
873     }
874 
875     @Test
876     void testWriteNamedStaticField() throws Exception {
877         FieldUtils.writeStaticField(StaticContainerChild.class, "mutablePublic", "new");
878         assertEquals("new", StaticContainer.mutablePublic);
879         assertNullPointerException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "mutableProtected", "new"));
880         assertNullPointerException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "mutablePackage", "new"));
881         assertNullPointerException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "mutablePrivate", "new"));
882         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PUBLIC", "new"));
883         assertNullPointerException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PROTECTED", "new"));
884         assertNullPointerException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PACKAGE", "new"));
885         assertNullPointerException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PRIVATE", "new"));
886         assertNullPointerException(() -> FieldUtils.writeStaticField(null, "IMMUTABLE_PRIVATE", "new"));
887         assertIllegalArgumentException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, null, "new"));
888         assertIllegalArgumentException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "", "new"));
889         assertIllegalArgumentException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, " ", "new"));
890     }
891 
892     @Test
893     void testWriteNamedStaticFieldForceAccess() throws Exception {
894         FieldUtils.writeStaticField(StaticContainerChild.class, "mutablePublic", "new", true);
895         assertEquals("new", StaticContainer.mutablePublic);
896         FieldUtils.writeStaticField(StaticContainerChild.class, "mutableProtected", "new", true);
897         assertEquals("new", StaticContainer.getMutableProtected());
898         FieldUtils.writeStaticField(StaticContainerChild.class, "mutablePackage", "new", true);
899         assertEquals("new", StaticContainer.getMutablePackage());
900         FieldUtils.writeStaticField(StaticContainerChild.class, "mutablePrivate", "new", true);
901         assertEquals("new", StaticContainer.getMutablePrivate());
902         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PUBLIC", "new", true));
903         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PROTECTED", "new", true));
904         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PACKAGE", "new", true));
905         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainerChild.class, "IMMUTABLE_PRIVATE", "new", true));
906         assertNullPointerException(() -> FieldUtils.writeStaticField(null, "IMMUTABLE_PRIVATE", "new", true));
907         assertIllegalArgumentException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, null, "new", true));
908         assertIllegalArgumentException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, "", "new", true));
909         assertIllegalArgumentException(() -> FieldUtils.writeStaticField(StaticContainerChild.class, " ", "new", true));
910     }
911 
912     @Test
913     void testWriteStaticField() throws Exception {
914         final Field field = StaticContainer.class.getDeclaredField("mutablePublic");
915         FieldUtils.writeStaticField(field, "new");
916         assertEquals("new", StaticContainer.mutablePublic);
917         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("mutableProtected"), "new"));
918         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("mutablePackage"), "new"));
919         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("mutablePrivate"), "new"));
920         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PUBLIC"), "new"));
921         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PROTECTED"), "new"));
922         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PACKAGE"), "new"));
923         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE"), "new"));
924         assertNullPointerException(() -> FieldUtils.writeStaticField(null, "new"));
925     }
926 
927     @Test
928     void testWriteStaticFieldForceAccess() throws Exception {
929         Field field = StaticContainer.class.getDeclaredField("mutablePublic");
930         FieldUtils.writeStaticField(field, "new", true);
931         assertEquals("new", StaticContainer.mutablePublic);
932         field = StaticContainer.class.getDeclaredField("mutableProtected");
933         FieldUtils.writeStaticField(field, "new", true);
934         assertEquals("new", StaticContainer.getMutableProtected());
935         field = StaticContainer.class.getDeclaredField("mutablePackage");
936         FieldUtils.writeStaticField(field, "new", true);
937         assertEquals("new", StaticContainer.getMutablePackage());
938         field = StaticContainer.class.getDeclaredField("mutablePrivate");
939         FieldUtils.writeStaticField(field, "new", true);
940         assertEquals("new", StaticContainer.getMutablePrivate());
941         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PUBLIC"), "new", true));
942         assertThrows(IllegalAccessException.class,
943                 () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PROTECTED"), "new", true));
944         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PACKAGE"), "new", true));
945         assertThrows(IllegalAccessException.class, () -> FieldUtils.writeStaticField(StaticContainer.class.getDeclaredField("IMMUTABLE_PRIVATE"), "new", true));
946         assertNullPointerException(() -> FieldUtils.writeStaticField(null, "new", true));
947     }
948 }