1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.reflect;
18
19 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNotSame;
25 import static org.junit.jupiter.api.Assertions.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertSame;
27 import static org.junit.jupiter.api.Assertions.assertThrows;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.junit.jupiter.api.Assumptions.assumeTrue;
30
31 import java.awt.Color;
32 import java.lang.reflect.Method;
33 import java.lang.reflect.Modifier;
34 import java.lang.reflect.Type;
35 import java.nio.file.Files;
36 import java.nio.file.LinkOption;
37 import java.nio.file.Path;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.Date;
42 import java.util.HashMap;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.Map;
46
47 import org.apache.commons.lang3.AbstractLangTest;
48 import org.apache.commons.lang3.ArrayUtils;
49 import org.apache.commons.lang3.ClassUtils;
50 import org.apache.commons.lang3.ClassUtils.Interfaces;
51 import org.apache.commons.lang3.JavaVersion;
52 import org.apache.commons.lang3.SystemUtils;
53 import org.apache.commons.lang3.math.NumberUtils;
54 import org.apache.commons.lang3.mutable.Mutable;
55 import org.apache.commons.lang3.mutable.MutableObject;
56 import org.apache.commons.lang3.reflect.testbed.Annotated;
57 import org.apache.commons.lang3.reflect.testbed.GenericConsumer;
58 import org.apache.commons.lang3.reflect.testbed.GenericParent;
59 import org.apache.commons.lang3.reflect.testbed.PublicChild;
60 import org.apache.commons.lang3.reflect.testbed.PublicSubBeanOtherPackage;
61 import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
62 import org.apache.commons.lang3.tuple.ImmutablePair;
63 import org.junit.jupiter.api.BeforeEach;
64 import org.junit.jupiter.api.Test;
65 import org.junit.jupiter.params.ParameterizedTest;
66 import org.junit.jupiter.params.provider.ValueSource;
67
68
69
70
71 class MethodUtilsTest extends AbstractLangTest {
72
73 protected abstract static class AbstractGetMatchingMethod implements InterfaceGetMatchingMethod {
74 public abstract void testMethod5(Exception exception);
75 }
76
77 protected abstract static class AbstractGetMatchingMethod2 implements InterfaceGetMatchingMethod {
78 @Override
79 public void testMethod6() { }
80 }
81
82 public static class ChildObject extends ParentObject implements PackagePrivateEmptyInterface {
83 }
84
85 private static final class ConcreteGetMatchingMethod2 extends AbstractGetMatchingMethod2 { }
86
87 private static final class ConcreteGetMatchingMethod22 extends AbstractGetMatchingMethod2 {
88 @Override
89 public void testMethod6() { }
90 }
91
92 private static final class GetMatchingMethodClass {
93
94 public void testMethod() {
95 }
96
97 public void testMethod(final long aLong) {
98 }
99
100 public void testMethod(final Long aLong) {
101 }
102
103 public void testMethod2(final Color aColor) {
104 }
105
106 public void testMethod2(final long aLong) {
107 }
108
109 public void testMethod2(final Long aLong) {
110 }
111
112 public void testMethod3(final long aLong, final Long anotherLong) {
113 }
114
115 public void testMethod3(final Long aLong, final long anotherLong) {
116 }
117
118 public void testMethod3(final Long aLong, final Long anotherLong) {
119 }
120
121 public void testMethod4(final Color aColor1, final Color aColor2) {
122 }
123
124 public void testMethod4(final Long aLong, final Long anotherLong) {
125 }
126
127 public void testMethod5(final Integer anInteger) {
128 }
129
130 public void testMethod5(final Number aNumber) {
131 }
132 }
133
134 private static final class GetMatchingMethodImpl extends AbstractGetMatchingMethod {
135 @Override
136 public void testMethod5(final Exception exception) {
137 }
138 }
139
140 public static class GrandParentObject {
141 }
142 public static class InheritanceBean {
143 public void testOne(final GrandParentObject obj) {
144 }
145
146 public void testOne(final Object obj) {
147 }
148
149 public void testOne(final ParentObject obj) {
150 }
151
152 public void testTwo(final GrandParentObject obj) {
153 }
154
155 public void testTwo(final Object obj) {
156 }
157
158 public void testTwo(final PackagePrivateEmptyInterface obj) {
159 }
160 }
161
162 static class InstanceLabel implements StaticLabel {
163 public String label() {
164 return "instance";
165 }
166 }
167 interface InterfaceGetMatchingMethod {
168 default void testMethod6() {
169 }
170 }
171
172 private static final class MethodDescriptor {
173 final Class<?> declaringClass;
174 final String name;
175 final Type[] parameterTypes;
176
177 MethodDescriptor(final Class<?> declaringClass, final String name, final Type... parameterTypes) {
178 this.declaringClass = declaringClass;
179 this.name = name;
180 this.parameterTypes = parameterTypes;
181 }
182 }
183
184 interface PackagePrivateEmptyInterface {
185
186 }
187
188 public static class ParentObject extends GrandParentObject {
189
190 }
191
192 private interface PrivateEmptyInterface {
193
194 }
195
196 public static class PublicImpl1OfPackagePrivateEmptyInterface implements PackagePrivateEmptyInterface {
197
198 }
199
200 public static class PublicImpl2OfPackagePrivateEmptyInterface implements PackagePrivateEmptyInterface {
201
202 }
203
204 static class StaticChild extends StaticParent {
205 public static String who() {
206 return "child";
207 }
208 }
209
210 public interface StaticLabel {
211 static String label() {
212 return "interface";
213 }
214 }
215
216 public static class StaticParent {
217 public static String who() {
218 return "parent";
219 }
220 }
221
222 public static class TestBean {
223
224 public static String bar() {
225 return "bar()";
226 }
227
228 public static String bar(final double d) {
229 return "bar(double)";
230 }
231
232 public static String bar(final int i) {
233 return "bar(int)";
234 }
235
236 public static String bar(final Integer i) {
237 return "bar(Integer)";
238 }
239
240 public static String bar(final Integer i, final String... s) {
241 return "bar(Integer, String...)";
242 }
243
244 public static String bar(final long... s) {
245 return "bar(long...)";
246 }
247
248 public static String bar(final Object o) {
249 return "bar(Object)";
250 }
251
252 public static String bar(final String s) {
253 return "bar(String)";
254 }
255
256 public static String bar(final String... s) {
257 return "bar(String...)";
258 }
259
260
261
262 public static String numOverload(final Byte... args) {
263 return "Byte...";
264 }
265
266 public static String numOverload(final Double... args) {
267 return "Double...";
268 }
269
270 public static String numOverload(final Float... args) {
271 return "Float...";
272 }
273
274 public static String numOverload(final Integer... args) {
275 return "Integer...";
276 }
277
278 public static String numOverload(final Long... args) {
279 return "Long...";
280 }
281
282 public static String numOverload(final Number... args) {
283 return "Number...";
284 }
285
286 public static String numOverload(final Short... args) {
287 return "Short...";
288 }
289
290 public static void oneParameterStatic(final String s) {
291
292 }
293
294 public static String staticInt(final int intArg) {
295 return "static int";
296 }
297
298 public static String staticIntIntVarArg(final int intArg, final int... args) {
299 return "static int, int...";
300 }
301
302 public static String staticIntLongVarArg(final int intArg, final long... args) {
303 return "static int, long...";
304 }
305
306 public static String staticIntStringVarArg(final int intArg, final String... args) {
307 return "static int, String...";
308 }
309
310 public static String staticPackagePrivateEmptyInterface(final PackagePrivateEmptyInterface... args) {
311 return "static PackagePrivateEmptyInterface...";
312 }
313
314 public static String varOverload(final Boolean... args) {
315 return "Boolean...";
316 }
317
318
319
320 public static String varOverload(final Byte... args) {
321 return "Byte...";
322 }
323
324 public static String varOverload(final Character... args) {
325 return "Character...";
326 }
327
328 public static String varOverload(final Double... args) {
329 return "Double...";
330 }
331
332 public static String varOverload(final Float... args) {
333 return "Float...";
334 }
335
336 public static String varOverload(final Integer... args) {
337 return "Integer...";
338 }
339
340 public static String varOverload(final Long... args) {
341 return "Long...";
342 }
343
344 public static String varOverload(final Number... args) {
345 return "Number...";
346 }
347
348 public static String varOverload(final Object... args) {
349 return "Object...";
350 }
351
352 public static String varOverload(final Short... args) {
353 return "Short...";
354 }
355
356 public static String varOverload(final String... args) {
357 return "String...";
358 }
359
360 public static ImmutablePair<String, Object[]> varOverloadEchoStatic(final Number... args) {
361 return new ImmutablePair<>("Number...", args);
362 }
363
364 public static ImmutablePair<String, Object[]> varOverloadEchoStatic(final String... args) {
365 return new ImmutablePair<>("String...", args);
366 }
367
368 static void verify(final ImmutablePair<String, Object[]> a, final ImmutablePair<String, Object[]> b) {
369 assertEquals(a.getLeft(), b.getLeft());
370 assertArrayEquals(a.getRight(), b.getRight());
371 }
372
373 static void verify(final ImmutablePair<String, Object[]> a, final Object obj) {
374 @SuppressWarnings("unchecked")
375 final ImmutablePair<String, Object[]> pair = (ImmutablePair<String, Object[]>) obj;
376 verify(a, pair);
377 }
378
379 boolean unboxBooleanArray;
380
381 boolean unboxByteArray;
382
383 boolean unboxCharArray;
384
385 boolean unboxDoubleArray;
386
387 boolean unboxFloatArray;
388
389 boolean unboxIntArray;
390
391 boolean unboxLongArray;
392
393 boolean unboxShortArray;
394
395 public String foo() {
396 return "foo()";
397 }
398
399 public String foo(final double d) {
400 return "foo(double)";
401 }
402
403 public String foo(final int i) {
404 return "foo(int)";
405 }
406
407 public String foo(final Integer i) {
408 return "foo(Integer)";
409 }
410
411 public String foo(final Integer i, final String... s) {
412 return "foo(int, String...)";
413 }
414
415 public String foo(final long l) {
416 return "foo(long)";
417 }
418
419 public String foo(final long... l) {
420 return "foo(long...)";
421 }
422
423 public String foo(final Object o) {
424 return "foo(Object)";
425 }
426
427 public String foo(final Object... s) {
428 return "foo(Object...)";
429 }
430
431 public String foo(final String s) {
432 return "foo(String)";
433 }
434
435 public String foo(final String... s) {
436 return "foo(String...)";
437 }
438
439 public String intIntVarArg(final int intArg, final int... args) {
440 return "int, int...";
441 }
442
443 public String intLongVarArg(final int intArg, final long... args) {
444 return "int, long...";
445 }
446
447 public String intStringVarArg(final int intArg, final String... args) {
448 return "int, String...";
449 }
450
451 public void oneParameter(final String s) {
452
453 }
454
455 public String packagePrivateEmptyInterface(final PackagePrivateEmptyInterface... args) {
456 return "PackagePrivateEmptyInterface...";
457 }
458
459 @SuppressWarnings("unused")
460 private String privateStringStuff() {
461 return "privateStringStuff()";
462 }
463
464 @SuppressWarnings("unused")
465 private String privateStringStuff(final double d) {
466 return "privateStringStuff(double)";
467 }
468
469 @SuppressWarnings("unused")
470 private String privateStringStuff(final int i) {
471 return "privateStringStuff(int)";
472 }
473
474 @SuppressWarnings("unused")
475 private String privateStringStuff(final Integer i) {
476 return "privateStringStuff(Integer)";
477 }
478
479 @SuppressWarnings("unused")
480 private String privateStringStuff(final Object s) {
481 return "privateStringStuff(Object)";
482 }
483
484 @SuppressWarnings("unused")
485 private String privateStringStuff(final String s) {
486 return "privateStringStuff(String)";
487 }
488
489 @SuppressWarnings("unused")
490 private void privateStuff() {
491 }
492
493 public boolean[] unboxing(final boolean... values) {
494 unboxBooleanArray = true;
495 return values;
496 }
497
498 public byte[] unboxing(final byte... values) {
499 unboxByteArray = true;
500 return values;
501 }
502
503 public char[] unboxing(final char... values) {
504 unboxCharArray = true;
505 return values;
506 }
507
508 public double[] unboxing(final double... values) {
509 unboxDoubleArray = true;
510 return values;
511 }
512
513 public float[] unboxing(final float... values) {
514 unboxFloatArray = true;
515 return values;
516 }
517
518 public int[] unboxing(final int... values) {
519 unboxIntArray = true;
520 return values;
521 }
522
523 public long[] unboxing(final long... values) {
524 unboxLongArray = true;
525 return values;
526 }
527
528 public short[] unboxing(final short... values) {
529 unboxShortArray = true;
530 return values;
531 }
532
533 public ImmutablePair<String, Object[]> varOverloadEcho(final Number... args) {
534 return new ImmutablePair<>("Number...", args);
535 }
536
537
538
539
540 public ImmutablePair<String, Object[]> varOverloadEcho(final String... args) {
541 return new ImmutablePair<>("String...", args);
542 }
543
544 }
545
546 static class TestBeanSubclass extends TestBean {
547 }
548
549 static class TestBeanWithInterfaces implements PrivateEmptyInterface {
550 public String foo() {
551 return "foo()";
552 }
553 }
554
555 private static class TestMutable implements Mutable<Object> {
556 @Override
557 public Object getValue() {
558 return null;
559 }
560
561 @Override
562 public void setValue(final Object value) {
563 }
564 }
565
566 private static final class TestMutableSubclass extends TestMutable {
567
568 }
569
570 private final Map<Class<?>, Class<?>[]> classCache = new HashMap<>();
571
572 private TestBean testBean;
573
574 private void expectMatchingAccessibleMethodParameterTypes(final Class<?> cls, final String methodName, final Class<?>[] requestTypes,
575 final Class<?>[] actualTypes) {
576 final Method m = MethodUtils.getMatchingAccessibleMethod(cls, methodName, requestTypes);
577 assertNotNull(m, "could not find any matches for " + methodName + " (" + (requestTypes == null ? null : toString(requestTypes)) + ")");
578 assertArrayEquals(actualTypes, m.getParameterTypes(), toString(m.getParameterTypes()) + " not equals " + toString(actualTypes));
579 }
580
581 @BeforeEach
582 public void setUp() {
583 testBean = new TestBean();
584 classCache.clear();
585 }
586
587 private Class<?>[] singletonArray(final Class<?> c) {
588 Class<?>[] result = classCache.get(c);
589 if (result == null) {
590 result = new Class[]{c};
591 classCache.put(c, result);
592 }
593 return result;
594 }
595
596 @Test
597 void testConstructor() throws Exception {
598 assertNotNull(MethodUtils.class.getConstructor().newInstance());
599 }
600
601 @Test
602 void testDistance() throws Exception {
603 final Method distanceMethod = MethodUtils.getMatchingMethod(MethodUtils.class, "distance", Class[].class, Class[].class);
604 distanceMethod.setAccessible(true);
605 assertEquals(-1, distanceMethod.invoke(null, new Class[] { String.class }, new Class[] { Date.class }));
606 assertEquals(0, distanceMethod.invoke(null, new Class[] { Date.class }, new Class[] { Date.class }));
607 assertEquals(1, distanceMethod.invoke(null, new Class[] { Integer.class }, new Class[] { ClassUtils.wrapperToPrimitive(Integer.class) }));
608 assertEquals(2, distanceMethod.invoke(null, new Class[] { Integer.class }, new Class[] { Object.class }));
609 distanceMethod.setAccessible(false);
610 }
611
612 @ParameterizedTest
613 @ValueSource(classes = {TestMutable.class, TestMutableSubclass.class})
614 void testGetAccessibleInterfaceMethod(final Class<?> clazz) throws Exception {
615 final Class<?>[][] p = {ArrayUtils.EMPTY_CLASS_ARRAY, null};
616 for (final Class<?>[] element : p) {
617 final Method method = clazz.getMethod("getValue", element);
618 final Method accessibleMethod = MethodUtils.getAccessibleMethod(method);
619 assertNotSame(accessibleMethod, method);
620 assertSame(Mutable.class, accessibleMethod.getDeclaringClass());
621 final Method accessibleMethod2 = MethodUtils.getAccessibleMethod(clazz, method);
622 assertNotSame(accessibleMethod2, method);
623 assertSame(Mutable.class, accessibleMethod2.getDeclaringClass());
624 }
625 }
626
627 @ParameterizedTest
628 @ValueSource(classes = {TestMutable.class, TestMutableSubclass.class})
629 void testGetAccessibleInterfaceMethodFromDescription(final Class<?> clazz) {
630 final Class<?>[][] p = { ArrayUtils.EMPTY_CLASS_ARRAY, null };
631 for (final Class<?>[] element : p) {
632 final Method accessibleMethod = MethodUtils.getAccessibleMethod(clazz, "getValue", element);
633 assertSame(Mutable.class, accessibleMethod.getDeclaringClass());
634 }
635 }
636
637 @Test
638 void testGetAccessibleMethodInaccessible() throws Exception {
639 assertNull(MethodUtils.getAccessibleMethod(TestBean.class.getDeclaredMethod("privateStuff")));
640 assertNull(MethodUtils.getAccessibleMethod(TestBean.class, TestBean.class.getDeclaredMethod("privateStuff")));
641 assertNull(MethodUtils.getAccessibleMethod(TestBeanSubclass.class, TestBean.class.getDeclaredMethod("privateStuff")));
642 }
643
644 @Test
645 void testGetAccessibleMethodPrivateInterface() throws Exception {
646 final Method expected = TestBeanWithInterfaces.class.getMethod("foo");
647 assertNotNull(expected);
648 final Method actual = MethodUtils.getAccessibleMethod(TestBeanWithInterfaces.class, "foo");
649 assertNull(actual);
650 }
651
652 @Test
653 void testGetAccessibleMethodPublicSub() throws Exception {
654
655 final int modifiers = PackageBean.class.getModifiers();
656 assertFalse(Modifier.isPrivate(modifiers));
657 assertFalse(Modifier.isProtected(modifiers));
658 assertFalse(Modifier.isPublic(modifiers));
659
660 new PublicSubBean().setBar("");
661
662 final PublicSubBean bean = new PublicSubBean();
663 assertEquals(bean.getFoo(), "This is foo", "Start value (foo)");
664 assertEquals(bean.getBar(), "This is bar", "Start value (bar)");
665 bean.setFoo("new foo");
666 bean.setBar("new bar");
667 assertEquals(bean.getFoo(), "new foo", "Set value (foo)");
668 assertEquals(bean.getBar(), "new bar", "Set value (bar)");
669
670
671 MethodUtils.invokeExactMethod(bean, "setFoo", "alpha");
672 assertEquals(bean.getFoo(), "alpha", "Set value (foo:2)");
673 MethodUtils.invokeExactMethod(bean, "setBar", "beta");
674 assertEquals(bean.getBar(), "beta", "Set value (bar:2)");
675
676 Method method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setFoo", String.class);
677 assertNotNull(method, "getAccessibleMethod() setFoo is Null");
678 method.invoke(bean, "1111");
679 assertEquals("1111", bean.getFoo(), "Set value (foo:3)");
680
681 method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setBar", String.class);
682 assertNotNull(method, "getAccessibleMethod() setBar is Null");
683 method.invoke(bean, "2222");
684 assertEquals("2222", bean.getBar(), "Set value (bar:3)");
685 }
686
687 @Test
688 void testGetAccessibleMethodPublicSubOtherPackage() throws Exception {
689
690 final int modifiers = Class.forName("org.apache.commons.lang3.reflect.testbed.PackageBeanOtherPackage").getModifiers();
691 assertFalse(Modifier.isPrivate(modifiers));
692 assertFalse(Modifier.isProtected(modifiers));
693 assertFalse(Modifier.isPublic(modifiers));
694
695 new PublicSubBeanOtherPackage().setBar("");
696
697 final PublicSubBeanOtherPackage bean = new PublicSubBeanOtherPackage();
698 assertEquals(bean.getFoo(), "This is foo", "Start value (foo)");
699 assertEquals(bean.getBar(), "This is bar", "Start value (bar)");
700 bean.setFoo("new foo");
701 bean.setBar("new bar");
702 assertEquals(bean.getFoo(), "new foo", "Set value (foo)");
703 assertEquals(bean.getBar(), "new bar", "Set value (bar)");
704
705
706 MethodUtils.invokeExactMethod(bean, "setFoo", "alpha");
707 assertEquals(bean.getFoo(), "alpha", "Set value (foo:2)");
708 MethodUtils.invokeExactMethod(bean, "setBar", "beta");
709 assertEquals(bean.getBar(), "beta", "Set value (bar:2)");
710
711 Method method = MethodUtils.getAccessibleMethod(PublicSubBeanOtherPackage.class, "setFoo", String.class);
712 assertNotNull(method, "getAccessibleMethod() setFoo is Null");
713 method.invoke(bean, "1111");
714 assertEquals("1111", bean.getFoo(), "Set value (foo:3)");
715
716 method = MethodUtils.getAccessibleMethod(PublicSubBeanOtherPackage.class, "setBar", String.class);
717 assertNotNull(method, "getAccessibleMethod() setBar is Null");
718 method.invoke(bean, "2222");
719 assertEquals("2222", bean.getBar(), "Set value (bar:3)");
720 }
721
722 @Test
723 void testGetAccessiblePublicMethod() throws Exception {
724 assertSame(MutableObject.class,
725 MethodUtils.getAccessibleMethod(MutableObject.class.getMethod("getValue", ArrayUtils.EMPTY_CLASS_ARRAY)).getDeclaringClass());
726 assertSame(MutableObject.class, MethodUtils
727 .getAccessibleMethod(MutableObject.class, MutableObject.class.getMethod("getValue", ArrayUtils.EMPTY_CLASS_ARRAY)).getDeclaringClass());
728 }
729
730 @Test
731 void testGetAccessiblePublicMethodFromDescription() {
732 assertSame(MutableObject.class, MethodUtils.getAccessibleMethod(MutableObject.class, "getValue", ArrayUtils.EMPTY_CLASS_ARRAY).getDeclaringClass());
733 }
734
735 @Test
736 void testGetAnnotationIllegalArgumentException1() {
737 assertNullPointerException(() -> MethodUtils.getAnnotation(FieldUtilsTest.class.getDeclaredMethods()[0], null, true, true));
738 }
739
740 @Test
741 void testGetAnnotationIllegalArgumentException2() {
742 assertNullPointerException(() -> MethodUtils.getAnnotation(null, Annotated.class, true, true));
743 }
744
745 @Test
746 void testGetAnnotationIllegalArgumentException3() {
747 assertNullPointerException(() -> MethodUtils.getAnnotation(null, null, true, true));
748 }
749
750 @Test
751 void testGetAnnotationNotSearchSupersAndNotIgnoreAccess() throws NoSuchMethodException {
752 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"), Annotated.class, false, false));
753 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class, false, false));
754 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"), Annotated.class, false, false));
755 assertNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"), Annotated.class, false, false));
756 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"), Annotated.class, false, false));
757 }
758
759 @Test
760 void testGetAnnotationNotSearchSupersButIgnoreAccess() throws NoSuchMethodException {
761 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"), Annotated.class, false, true));
762 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class, false, true));
763 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"), Annotated.class, false, true));
764 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"), Annotated.class, false, true));
765 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"), Annotated.class, false, true));
766 }
767
768 @Test
769 void testGetAnnotationSearchSupersAndIgnoreAccess() throws NoSuchMethodException {
770 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"), Annotated.class, true, true));
771 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class, true, true));
772 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"), Annotated.class, true, true));
773 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"), Annotated.class, true, true));
774 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"), Annotated.class, true, true));
775 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentNotAnnotatedMethod", String.class), Annotated.class, true, true));
776 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentProtectedAnnotatedMethod", String.class), Annotated.class, true,
777 true));
778 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getDeclaredMethod("privateAnnotatedMethod", String.class), Annotated.class, true,
779 true));
780 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("publicAnnotatedMethod", String.class), Annotated.class, true, true));
781 }
782
783 @Test
784 void testGetAnnotationSearchSupersButNotIgnoreAccess() throws NoSuchMethodException {
785 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"), Annotated.class, true, false));
786 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class, true, false));
787 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"), Annotated.class, true, false));
788 assertNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"), Annotated.class, true, false));
789 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"), Annotated.class, true, false));
790 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentNotAnnotatedMethod", String.class), Annotated.class, true, false));
791 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentProtectedAnnotatedMethod", String.class), Annotated.class, true,
792 false));
793 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getDeclaredMethod("privateAnnotatedMethod", String.class), Annotated.class, true,
794 false));
795 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("publicAnnotatedMethod", String.class), Annotated.class, true, false));
796 }
797
798 @Test
799 void testGetMatchingAccessibleMethod() {
800 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", ArrayUtils.EMPTY_CLASS_ARRAY, ArrayUtils.EMPTY_CLASS_ARRAY);
801 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", null, ArrayUtils.EMPTY_CLASS_ARRAY);
802 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(String.class), singletonArray(String.class));
803 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Object.class), singletonArray(Object.class));
804 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Boolean.class), singletonArray(Object.class));
805 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Byte.class), singletonArray(Integer.TYPE));
806 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Byte.TYPE), singletonArray(Integer.TYPE));
807 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Short.class), singletonArray(Integer.TYPE));
808 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Short.TYPE), singletonArray(Integer.TYPE));
809 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Character.class), singletonArray(Integer.TYPE));
810 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Character.TYPE), singletonArray(Integer.TYPE));
811 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Integer.class), singletonArray(Integer.class));
812 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Integer.TYPE), singletonArray(Integer.TYPE));
813 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Long.class), singletonArray(Long.TYPE));
814 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Long.TYPE), singletonArray(Long.TYPE));
815 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Float.class), singletonArray(Double.TYPE));
816 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Float.TYPE), singletonArray(Double.TYPE));
817 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Double.class), singletonArray(Double.TYPE));
818 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Double.TYPE), singletonArray(Double.TYPE));
819 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Double.TYPE), singletonArray(Double.TYPE));
820 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", new Class[] { String.class, String.class }, new Class[] { String[].class });
821 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", new Class[] { Integer.TYPE, String.class, String.class },
822 new Class[] { Integer.class, String[].class });
823 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testOne", singletonArray(ParentObject.class), singletonArray(ParentObject.class));
824 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testOne", singletonArray(ChildObject.class), singletonArray(ParentObject.class));
825 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testTwo", singletonArray(ParentObject.class),
826 singletonArray(GrandParentObject.class));
827 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testTwo", singletonArray(ChildObject.class), singletonArray(PackagePrivateEmptyInterface.class));
828
829 expectMatchingAccessibleMethodParameterTypes(Files.class, "exists", singletonArray(Path.class), new Class[] { Path.class, LinkOption[].class });
830 }
831
832 @ParameterizedTest
833 @ValueSource(classes = {TestMutable.class, TestMutableSubclass.class})
834 void testGetMatchingAccessibleMethodOnNonPublicClass(final Class<?> clazz) {
835 assertSame(Mutable.class, MethodUtils.getMatchingAccessibleMethod(clazz, "getValue").getDeclaringClass());
836 assertSame(Mutable.class,
837 MethodUtils.getMatchingAccessibleMethod(clazz, "setValue", Object.class).getDeclaringClass());
838 }
839
840 @Test
841 void testGetMatchingAccessibleMethodOnNonPublicJdkClass() {
842 assertSame(List.class,
843 MethodUtils.getMatchingAccessibleMethod(Collections.emptyList().getClass(), "size").getDeclaringClass());
844 assertSame(List.class,
845 MethodUtils.getMatchingAccessibleMethod(Arrays.asList(1, 2).getClass(), "size").getDeclaringClass());
846 assertSame(Map.class,
847 MethodUtils.getMatchingAccessibleMethod(Collections.emptyMap().getClass(), "size").getDeclaringClass());
848 }
849
850 @Test
851 void testGetMatchingAccessibleMethodWithNoPublicDeclaration() {
852 assertSame(TestBeanWithInterfaces.class,
853 MethodUtils.getMatchingAccessibleMethod(TestBeanWithInterfaces.class, "foo").getDeclaringClass());
854 }
855
856 @Test
857 void testGetMatchingMethod() throws NoSuchMethodException {
858 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod"), GetMatchingMethodClass.class.getMethod("testMethod"));
859 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", Long.TYPE),
860 GetMatchingMethodClass.class.getMethod("testMethod", Long.TYPE));
861 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", Long.class),
862 GetMatchingMethodClass.class.getMethod("testMethod", Long.class));
863 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", (Class<?>) null),
864 GetMatchingMethodClass.class.getMethod("testMethod", Long.class));
865 assertThrows(IllegalStateException.class, () -> MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod2", (Class<?>) null));
866 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.TYPE, Long.class),
867 GetMatchingMethodClass.class.getMethod("testMethod3", Long.TYPE, Long.class));
868 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.class, Long.TYPE),
869 GetMatchingMethodClass.class.getMethod("testMethod3", Long.class, Long.TYPE));
870 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", null, Long.TYPE),
871 GetMatchingMethodClass.class.getMethod("testMethod3", Long.class, Long.TYPE));
872 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.TYPE, null),
873 GetMatchingMethodClass.class.getMethod("testMethod3", Long.TYPE, Long.class));
874 assertThrows(IllegalStateException.class, () -> MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod4", null, null));
875
876 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod5", Integer.TYPE),
877 GetMatchingMethodClass.class.getMethod("testMethod5", Integer.class));
878 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod5", Integer.class),
879 GetMatchingMethodClass.class.getMethod("testMethod5", Integer.class));
880 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodImpl.class, "testMethod5", RuntimeException.class),
881 GetMatchingMethodImpl.class.getMethod("testMethod5", Exception.class));
882 assertEquals(GetMatchingMethodImpl.class.getMethod("testMethod6"), MethodUtils.getMatchingMethod(GetMatchingMethodImpl.class, "testMethod6"));
883 assertNullPointerException(() -> MethodUtils.getMatchingMethod(null, "testMethod5", RuntimeException.class));
884 Method testMethod6 = MethodUtils.getMatchingMethod(ConcreteGetMatchingMethod2.class, "testMethod6");
885 assertNotNull(testMethod6);
886 assertEquals(AbstractGetMatchingMethod2.class, testMethod6.getDeclaringClass());
887 testMethod6 = MethodUtils.getMatchingMethod(ConcreteGetMatchingMethod22.class, "testMethod6");
888 assertNotNull(testMethod6);
889 assertEquals(ConcreteGetMatchingMethod22.class, testMethod6.getDeclaringClass());
890 }
891
892 @Test
893 void testGetMethodObject() throws Exception {
894 assertEquals(MutableObject.class.getMethod("getValue", ArrayUtils.EMPTY_CLASS_ARRAY),
895 MethodUtils.getMethodObject(MutableObject.class, "getValue", ArrayUtils.EMPTY_CLASS_ARRAY));
896 assertNull(MethodUtils.getMethodObject(MutableObject.class, "does not exist, at all", ArrayUtils.EMPTY_CLASS_ARRAY));
897 assertNull(MethodUtils.getMethodObject(null, "does not exist, at all", ArrayUtils.EMPTY_CLASS_ARRAY));
898 assertNull(MethodUtils.getMethodObject(null, null, ArrayUtils.EMPTY_CLASS_ARRAY));
899 assertNull(MethodUtils.getMethodObject(MutableObject.class, null, ArrayUtils.EMPTY_CLASS_ARRAY));
900
901 assertNull(MethodUtils.getMethodObject(MutableObject.class, "getValue", new Class[] { null }));
902
903 assertNull(MethodUtils.getMethodObject(MutableObject.class, "equals", new Class[] { null }));
904 assertNull(MethodUtils.getMethodObject(MutableObject.class, "equals", new Class[] { String.class, null, String.class }));
905 }
906
907
908
909
910 @Test
911 @Annotated
912 public void testGetMethodsListWithAnnotation() throws NoSuchMethodException {
913 assertEquals(0, MethodUtils.getMethodsListWithAnnotation(Object.class, Annotated.class).size());
914 final List<Method> methodWithAnnotation = MethodUtils.getMethodsListWithAnnotation(MethodUtilsTest.class, Annotated.class);
915 assertEquals(2, methodWithAnnotation.size());
916 assertTrue(methodWithAnnotation.contains(MethodUtilsTest.class.getMethod("testGetMethodsWithAnnotation")));
917 assertTrue(methodWithAnnotation.contains(MethodUtilsTest.class.getMethod("testGetMethodsListWithAnnotation")));
918 }
919
920 @Test
921 void testGetMethodsListWithAnnotationNullPointerException1() {
922 assertNullPointerException(() -> MethodUtils.getMethodsListWithAnnotation(FieldUtilsTest.class, null));
923 }
924
925 @Test
926 void testGetMethodsListWithAnnotationNullPointerException2() {
927 assertNullPointerException(() -> MethodUtils.getMethodsListWithAnnotation(null, Annotated.class));
928 }
929
930 @Test
931 void testGetMethodsListWithAnnotationNullPointerException3() {
932 assertNullPointerException(() -> MethodUtils.getMethodsListWithAnnotation(null, null));
933 }
934
935 @Test
936 @Annotated
937 public void testGetMethodsWithAnnotation() throws NoSuchMethodException {
938 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class));
939 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(MethodUtilsTest.class, Annotated.class);
940 assertEquals(2, methodsWithAnnotation.length);
941 assertTrue(ArrayUtils.contains(methodsWithAnnotation, MethodUtilsTest.class.getMethod("testGetMethodsWithAnnotation")));
942 assertTrue(ArrayUtils.contains(methodsWithAnnotation, MethodUtilsTest.class.getMethod("testGetMethodsListWithAnnotation")));
943 }
944
945 @Test
946 void testGetMethodsWithAnnotationIllegalArgumentException1() {
947 assertNullPointerException(() -> MethodUtils.getMethodsWithAnnotation(FieldUtilsTest.class, null));
948 }
949
950 @Test
951 void testGetMethodsWithAnnotationIllegalArgumentException2() {
952 assertNullPointerException(() -> MethodUtils.getMethodsWithAnnotation(null, Annotated.class));
953 }
954
955 @Test
956 void testGetMethodsWithAnnotationIllegalArgumentException3() {
957 assertNullPointerException(() -> MethodUtils.getMethodsWithAnnotation(null, null));
958 }
959
960 @Test
961 void testGetMethodsWithAnnotationNotSearchSupersAndNotIgnoreAccess() {
962 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, false, false));
963 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, false, false);
964 assertEquals(1, methodsWithAnnotation.length);
965 assertEquals("PublicChild.publicAnnotatedMethod",
966 methodsWithAnnotation[0].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[0].getName());
967 }
968
969 @Test
970 void testGetMethodsWithAnnotationNotSearchSupersButIgnoreAccess() {
971 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, false, true));
972 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, false, true);
973 assertEquals(2, methodsWithAnnotation.length);
974 assertEquals("PublicChild", methodsWithAnnotation[0].getDeclaringClass().getSimpleName());
975 assertEquals("PublicChild", methodsWithAnnotation[1].getDeclaringClass().getSimpleName());
976 assertTrue(methodsWithAnnotation[0].getName().endsWith("AnnotatedMethod"));
977 assertTrue(methodsWithAnnotation[1].getName().endsWith("AnnotatedMethod"));
978 }
979
980 @Test
981 void testGetMethodsWithAnnotationSearchSupersAndIgnoreAccess() {
982 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, true, true));
983 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, true, true);
984 assertEquals(4, methodsWithAnnotation.length);
985 assertEquals("PublicChild", methodsWithAnnotation[0].getDeclaringClass().getSimpleName());
986 assertEquals("PublicChild", methodsWithAnnotation[1].getDeclaringClass().getSimpleName());
987 assertTrue(methodsWithAnnotation[0].getName().endsWith("AnnotatedMethod"));
988 assertTrue(methodsWithAnnotation[1].getName().endsWith("AnnotatedMethod"));
989 assertEquals("Foo.doIt", methodsWithAnnotation[2].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[2].getName());
990 assertEquals("Parent.parentProtectedAnnotatedMethod",
991 methodsWithAnnotation[3].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[3].getName());
992 }
993
994 @Test
995 void testGetMethodsWithAnnotationSearchSupersButNotIgnoreAccess() {
996 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, true, false));
997 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, true, false);
998 assertEquals(2, methodsWithAnnotation.length);
999 assertEquals("PublicChild.publicAnnotatedMethod",
1000 methodsWithAnnotation[0].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[0].getName());
1001 assertEquals("Foo.doIt", methodsWithAnnotation[1].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[1].getName());
1002 }
1003
1004 @Test
1005 void testGetOverrideHierarchyExcludingInterfaces() {
1006 final Method method = MethodUtils.getAccessibleMethod(StringParameterizedChild.class, "consume", String.class);
1007 final Iterator<MethodDescriptor> expected =
1008 Arrays.asList(new MethodDescriptor(StringParameterizedChild.class, "consume", String.class),
1009 new MethodDescriptor(GenericParent.class, "consume", GenericParent.class.getTypeParameters()[0]))
1010 .iterator();
1011 for (final Method m : MethodUtils.getOverrideHierarchy(method, Interfaces.EXCLUDE)) {
1012 assertTrue(expected.hasNext());
1013 final MethodDescriptor md = expected.next();
1014 assertEquals(md.declaringClass, m.getDeclaringClass());
1015 assertEquals(md.name, m.getName());
1016 assertEquals(md.parameterTypes.length, m.getParameterTypes().length);
1017 for (int i = 0; i < md.parameterTypes.length; i++) {
1018 assertTrue(TypeUtils.equals(md.parameterTypes[i], m.getGenericParameterTypes()[i]));
1019 }
1020 }
1021 assertFalse(expected.hasNext());
1022 }
1023
1024 @Test
1025 void testGetOverrideHierarchyIncludingInterfaces() {
1026 final Method method = MethodUtils.getAccessibleMethod(StringParameterizedChild.class, "consume", String.class);
1027 final Iterator<MethodDescriptor> expected =
1028 Arrays.asList(new MethodDescriptor(StringParameterizedChild.class, "consume", String.class),
1029 new MethodDescriptor(GenericParent.class, "consume", GenericParent.class.getTypeParameters()[0]),
1030 new MethodDescriptor(GenericConsumer.class, "consume", GenericConsumer.class.getTypeParameters()[0]))
1031 .iterator();
1032 for (final Method m : MethodUtils.getOverrideHierarchy(method, Interfaces.INCLUDE)) {
1033 assertTrue(expected.hasNext());
1034 final MethodDescriptor md = expected.next();
1035 assertEquals(md.declaringClass, m.getDeclaringClass());
1036 assertEquals(md.name, m.getName());
1037 assertEquals(md.parameterTypes.length, m.getParameterTypes().length);
1038 for (int i = 0; i < md.parameterTypes.length; i++) {
1039 assertTrue(TypeUtils.equals(md.parameterTypes[i], m.getGenericParameterTypes()[i]));
1040 }
1041 }
1042 assertFalse(expected.hasNext());
1043 }
1044
1045 @Test
1046 void testInvokeExactMethod() throws Exception {
1047 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1048 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo"));
1049 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo", (Object[]) null));
1050 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo", null, null));
1051 assertEquals("foo(String)", MethodUtils.invokeExactMethod(testBean, "foo", ""));
1052 assertEquals("foo(Object)", MethodUtils.invokeExactMethod(testBean, "foo", new Object()));
1053 assertEquals("foo(Integer)", MethodUtils.invokeExactMethod(testBean, "foo", NumberUtils.INTEGER_ONE));
1054 assertEquals("foo(double)", MethodUtils.invokeExactMethod(testBean, "foo", new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1055 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, "foo", NumberUtils.BYTE_ONE));
1056 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, "foo", NumberUtils.LONG_ONE));
1057 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, "foo", Boolean.TRUE));
1058 assertThrows(NullPointerException.class, () -> MethodUtils.invokeExactMethod(null, "foo", NumberUtils.BYTE_ONE));
1059 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, null, NumberUtils.BYTE_ONE));
1060 assertThrows(NullPointerException.class,
1061 () -> MethodUtils.invokeExactMethod(null, "foo", new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1062 assertThrows(NoSuchMethodException.class,
1063 () -> MethodUtils.invokeExactMethod(testBean, null, new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1064 }
1065
1066 @Test
1067 void testInvokeExactStaticMethod() throws Exception {
1068 assertEquals("bar()", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1069 assertEquals("bar()", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", (Object[]) null));
1070 assertEquals("bar()", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", null, null));
1071 assertEquals("bar(String)", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", ""));
1072 assertEquals("bar(Object)", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", new Object()));
1073 assertEquals("bar(Integer)", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", NumberUtils.INTEGER_ONE));
1074 assertEquals("bar(double)",
1075 MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1076 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", NumberUtils.BYTE_ONE));
1077 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", NumberUtils.LONG_ONE));
1078 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", Boolean.TRUE));
1079 }
1080
1081 @Test
1082 void testInvokeJavaVarArgsOverloadingResolution() throws Exception {
1083
1084 assertEquals("Byte...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (byte) 1, (byte) 2));
1085 assertEquals("Short...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (short) 1, (short) 2));
1086 assertEquals("Integer...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 2));
1087 assertEquals("Long...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1L, 2L));
1088 assertEquals("Float...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1f, 2f));
1089 assertEquals("Double...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1d, 2d));
1090 assertEquals("Boolean...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", true, false));
1091
1092 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 1.1));
1093 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 1L));
1094 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1d, 1f));
1095 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (short) 1, (byte) 1));
1096 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "numOverload", ArrayUtils.EMPTY_OBJECT_ARRAY));
1097 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "numOverload", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1098 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "numOverload", (Object[]) ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY));
1099
1100 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, "s"));
1101 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, true));
1102 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1.1, true));
1103 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 'c', true));
1104 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 'c'));
1105 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 'c', "s"));
1106 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", ArrayUtils.EMPTY_OBJECT_ARRAY));
1107 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1108 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (Object[]) ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY));
1109 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload"));
1110
1111 assertEquals("String...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", "a", "b"));
1112 assertEquals("Character...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 'a', 'b'));
1113 }
1114
1115 @Test
1116 void testInvokeMethod() throws Exception {
1117 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1118 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo"));
1119 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo", (Object[]) null));
1120 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo", null, null));
1121 assertEquals("foo(String)", MethodUtils.invokeMethod(testBean, "foo", ""));
1122 assertEquals("foo(Object)", MethodUtils.invokeMethod(testBean, "foo", new Object()));
1123 assertEquals("foo(Object)", MethodUtils.invokeMethod(testBean, "foo", Boolean.TRUE));
1124 assertEquals("foo(Integer)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.INTEGER_ONE));
1125 assertEquals("foo(int)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.BYTE_ONE));
1126 assertEquals("foo(long)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.LONG_ONE));
1127 assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.DOUBLE_ONE));
1128 assertEquals("foo(String...)", MethodUtils.invokeMethod(testBean, "foo", "a", "b", "c"));
1129 assertEquals("foo(String...)", MethodUtils.invokeMethod(testBean, "foo", "a", "b", "c"));
1130 assertEquals("foo(int, String...)", MethodUtils.invokeMethod(testBean, "foo", 5, "a", "b", "c"));
1131 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", 1L, 2L));
1132 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", 1, 2));
1133 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", (byte) 1, (byte) 2));
1134 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", (short) 1, (short) 2));
1135 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", (char) 1, (char) 2));
1136 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
1137 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", 17, 23, 42));
1138 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
1139 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", 17, 23, 42));
1140 assertNullPointerException(() -> MethodUtils.invokeMethod(null, "foo", 1, 2));
1141 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, null, 1, 2));
1142 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(new Object(), "nonExistent", new Object[] { "val" }, new Class<?>[] { null }));
1143 }
1144
1145 @Test
1146 void testInvokeMethod_VarArgsWithNullValues() throws Exception {
1147 assertEquals("String...", MethodUtils.invokeMethod(testBean, "varOverload", "a", null, "c"));
1148 assertEquals("String...", MethodUtils.invokeMethod(testBean, "varOverload", "a", "b", null));
1149 assertEquals("String...", MethodUtils.invokeMethod(testBean, "varOverload", new String[] { "a" }, new Class<?>[] { String.class }));
1150 assertThrows(NoSuchMethodException.class,
1151 () -> assertEquals("String...", MethodUtils.invokeMethod(testBean, "doesn't exist", new String[] { "a" }, new Class<?>[] { null })));
1152 }
1153
1154 @Test
1155 void testInvokeMethod1PlusVarArgs() throws Exception {
1156
1157 assertEquals("int, String...", MethodUtils.invokeMethod(testBean, "intStringVarArg", 1));
1158 assertEquals("int, String...", MethodUtils.invokeMethod(testBean, "intStringVarArg", 1, "s"));
1159 assertEquals("int, String...", MethodUtils.invokeMethod(testBean, "intStringVarArg", 1, "s1", "s2"));
1160 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "intStringVarArg", 1, "s1", 5));
1161
1162 assertEquals("int, long...", MethodUtils.invokeMethod(testBean, "intLongVarArg", 1));
1163 assertEquals("int, long...", MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, 2L));
1164 assertEquals("int, long...", MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, 2L, 3L));
1165 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, "s1", 5));
1166
1167 assertEquals("int, int...", MethodUtils.invokeMethod(testBean, "intIntVarArg", 1));
1168 assertEquals("int, int...", MethodUtils.invokeMethod(testBean, "intIntVarArg", 1, 2));
1169 assertEquals("int, int...", MethodUtils.invokeMethod(testBean, "intIntVarArg", 1, 2, 3));
1170 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, "s1", 5));
1171 }
1172
1173 @Test
1174 void testInvokeMethodForceAccessNoArgs() throws Exception {
1175 assertEquals("privateStringStuff()", MethodUtils.invokeMethod(testBean, true, "privateStringStuff"));
1176 }
1177
1178 @Test
1179 void testInvokeMethodForceAccessWithArgs() throws Exception {
1180 assertEquals("privateStringStuff(Integer)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", 5));
1181 assertEquals("privateStringStuff(double)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", 5.0d));
1182 assertEquals("privateStringStuff(String)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", "Hi There"));
1183 assertEquals("privateStringStuff(Object)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", new Date()));
1184 assertNullPointerException(() -> MethodUtils.invokeMethod(null, true, "privateStringStuff", "Hi There"));
1185 assertNullPointerException(() -> MethodUtils.invokeMethod(testBean, true, null, "Hi There"));
1186 }
1187
1188 @Test
1189 void testInvokeMethodIgnoresPrivateInterfaceMethod() throws Exception {
1190
1191 assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9));
1192 final Class<?> labels = Class.forName("org.apache.commons.lang3.reflect.testbed9.PrivateInterfaceLabels");
1193 final Object bean = labels.getMethod("newBean").invoke(null);
1194 assertEquals("bean", MethodUtils.invokeMethod(bean, "label"));
1195 assertNull(MethodUtils.getAccessibleMethod(bean.getClass(), "label"));
1196 }
1197
1198 @Test
1199 void testInvokeMethodIgnoresStaticInterfaceMethod() throws Exception {
1200 assertSame(InstanceLabel.class, MethodUtils.getMatchingAccessibleMethod(InstanceLabel.class, "label").getDeclaringClass());
1201 assertEquals("instance", MethodUtils.invokeMethod(new InstanceLabel(), "label"));
1202 assertNull(MethodUtils.getAccessibleMethod(InstanceLabel.class, "label"));
1203 }
1204
1205 @Test
1206 void testInvokeMethodOnNonPublicClass() throws Exception {
1207 assertEquals(0, MethodUtils.invokeMethod(Collections.emptyList(), "size"));
1208 assertEquals(2, MethodUtils.invokeMethod(Arrays.asList(1, 2), "size"));
1209 assertEquals(0, MethodUtils.invokeMethod(Collections.emptyMap(), "size"));
1210 assertEquals(0, MethodUtils.invokeMethod(Collections.unmodifiableList(new ArrayList<>()), "size"));
1211 assertNull(MethodUtils.invokeMethod(new TestMutable(), "getValue"));
1212 }
1213
1214 @Test
1215 void testInvokeMethodVarArgsNotUniqueResolvable() throws Exception {
1216 assertEquals("Boolean...", MethodUtils.invokeMethod(testBean, "varOverload", new Object[] { null }));
1217 assertEquals("Object...", MethodUtils.invokeMethod(testBean, "varOverload", (Object[]) null));
1218 }
1219
1220 @Test
1221 void testInvokeMethodVarArgsOfInterface() throws Exception {
1222
1223 assertEquals("PackagePrivateEmptyInterface...", MethodUtils.invokeMethod(testBean, "packagePrivateEmptyInterface",
1224 new PublicImpl1OfPackagePrivateEmptyInterface(), new PublicImpl2OfPackagePrivateEmptyInterface()));
1225 assertEquals("PackagePrivateEmptyInterface...", MethodUtils.invokeMethod(testBean, "packagePrivateEmptyInterface", new PackagePrivateEmptyInterface() {
1226
1227 }, new PackagePrivateEmptyInterface() {
1228
1229 }));
1230 }
1231
1232 @Test
1233 void testInvokeMethodVarArgsUnboxingBooleanArray() throws Exception {
1234 final TestBean testBean = new TestBean();
1235 final boolean[] actual = (boolean[]) MethodUtils.invokeMethod(testBean, "unboxing", Boolean.TRUE, Boolean.FALSE);
1236 assertArrayEquals(new boolean[] { true, false }, actual);
1237 assertTrue(testBean.unboxBooleanArray);
1238 }
1239
1240 @Test
1241 void testInvokeMethodVarArgsUnboxingByteArray() throws Exception {
1242 final TestBean testBean = new TestBean();
1243 final byte[] actual = (byte[]) MethodUtils.invokeMethod(testBean, "unboxing", Byte.valueOf((byte) 1), Byte.valueOf((byte) 2));
1244 assertArrayEquals(new byte[] { 1, 2 }, actual);
1245 assertTrue(testBean.unboxByteArray);
1246 }
1247
1248 @Test
1249 void testInvokeMethodVarArgsUnboxingCharArray() throws Exception {
1250 final TestBean testBean = new TestBean();
1251 final char[] actual = (char[]) MethodUtils.invokeMethod(testBean, "unboxing", Character.valueOf((char) 1), Character.valueOf((char) 2));
1252 assertArrayEquals(new char[] { 1, 2 }, actual);
1253 assertTrue(testBean.unboxCharArray);
1254 }
1255
1256 @Test
1257 void testInvokeMethodVarArgsUnboxingDoubleArray() throws Exception {
1258 final TestBean testBean = new TestBean();
1259 final double[] actual = (double[]) MethodUtils.invokeMethod(testBean, "unboxing", Double.valueOf(1), Double.valueOf(2));
1260 assertArrayEquals(new double[] { 1, 2 }, actual);
1261 assertTrue(testBean.unboxDoubleArray);
1262 }
1263
1264 @Test
1265 void testInvokeMethodVarArgsUnboxingFloatArray() throws Exception {
1266 final TestBean testBean = new TestBean();
1267 final float[] actual = (float[]) MethodUtils.invokeMethod(testBean, "unboxing", Float.valueOf(1), Float.valueOf(2));
1268 assertArrayEquals(new float[] { 1, 2 }, actual);
1269 assertTrue(testBean.unboxFloatArray);
1270 }
1271
1272 @Test
1273 void testInvokeMethodVarArgsUnboxingIntArray() throws Exception {
1274 final TestBean testBean = new TestBean();
1275 final int[] actual = (int[]) MethodUtils.invokeMethod(testBean, "unboxing", Integer.valueOf(1), Integer.valueOf(2));
1276 assertArrayEquals(new int[] { 1, 2 }, actual);
1277 assertTrue(testBean.unboxIntArray);
1278 }
1279
1280 @Test
1281 void testInvokeMethodVarArgsUnboxingLongArray() throws Exception {
1282 final TestBean testBean = new TestBean();
1283 final long[] actual = (long[]) MethodUtils.invokeMethod(testBean, "unboxing", Long.valueOf(1), Long.valueOf(2));
1284 assertArrayEquals(new long[] { 1, 2 }, actual);
1285 assertTrue(testBean.unboxLongArray);
1286 }
1287
1288 @Test
1289 void testInvokeMethodVarArgsUnboxingShortArray() throws Exception {
1290 final TestBean testBean = new TestBean();
1291 final short[] actual = (short[]) MethodUtils.invokeMethod(testBean, "unboxing", Short.valueOf((short) 1), Short.valueOf((short) 2));
1292 assertArrayEquals(new short[] { 1, 2 }, actual);
1293 assertTrue(testBean.unboxShortArray);
1294 }
1295
1296 @Test
1297 void testInvokeStaticMethod() throws Exception {
1298 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar"));
1299 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1300 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (Object[]) null));
1301 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar", null, null));
1302 assertEquals("bar(String)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", ""));
1303 assertEquals("bar(Object)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", new Object()));
1304 assertEquals("bar(Object)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", Boolean.TRUE));
1305 assertEquals("bar(Integer)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.INTEGER_ONE));
1306 assertEquals("bar(int)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.BYTE_ONE));
1307 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", NumberUtils.BYTE_ONE));
1308 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", NumberUtils.SHORT_ONE));
1309 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", NumberUtils.INTEGER_ONE));
1310 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", 'a'));
1311 assertEquals("bar(double)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.DOUBLE_ONE));
1312 assertEquals("bar(String...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", "a", "b"));
1313 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", 1L, 2L));
1314 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (byte) 1, (byte) 2));
1315 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (short) 1, (short) 2));
1316 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", 1, 2));
1317 assertEquals("bar(Integer, String...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.INTEGER_ONE, "a", "b"));
1318
1319 assertThrows(NoSuchMethodException.class,
1320 () -> assertEquals("bar(Integer, String...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.SHORT_ONE, "a", "b")));
1321 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }),
1322 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", "x", "y"));
1323 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }),
1324 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", 17, 23, 42));
1325 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }),
1326 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", "x", "y"));
1327 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }),
1328 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", 17, 23, 42));
1329 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeStaticMethod(TestBean.class, "does_not_exist"));
1330 }
1331
1332 @Test
1333 void testInvokeStaticMethod1PlusVarArgs() throws Exception {
1334
1335 assertEquals("static int, String...", MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1));
1336 assertEquals("static int, String...", MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1, "s"));
1337 assertEquals("static int, String...", MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1, "s1", "s2"));
1338 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1, "s1", 5));
1339
1340 assertEquals("static int, long...", MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1));
1341 assertEquals("static int, long...", MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1, 2L));
1342 assertEquals("static int, long...", MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1, 2L, 3L));
1343 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1, "s1", 5));
1344
1345 assertEquals("static int, int...", MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1));
1346 assertEquals("static int, int...", MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, 2));
1347 assertEquals("static int, int...", MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, 2, 3));
1348 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, "s1", 5));
1349 }
1350
1351 @Test
1352 void testInvokeStaticMethodOnNonPublicSubclass() throws Exception {
1353
1354 assertSame(StaticChild.class, MethodUtils.getMatchingAccessibleMethod(StaticChild.class, "who").getDeclaringClass());
1355 assertEquals("child", MethodUtils.invokeStaticMethod(StaticChild.class, "who"));
1356 }
1357
1358 @Test
1359 void testInvokeStaticMethodVarArgsOfInterface() throws Exception {
1360
1361 assertEquals("static PackagePrivateEmptyInterface...", MethodUtils.invokeStaticMethod(TestBean.class, "staticPackagePrivateEmptyInterface",
1362 new PublicImpl1OfPackagePrivateEmptyInterface(), new PublicImpl2OfPackagePrivateEmptyInterface()));
1363 assertEquals("static PackagePrivateEmptyInterface...",
1364 MethodUtils.invokeStaticMethod(TestBean.class, "staticPackagePrivateEmptyInterface", new PackagePrivateEmptyInterface() {
1365
1366 }, new PackagePrivateEmptyInterface() {
1367
1368 }));
1369 }
1370
1371 @Test
1372 void testNullArgument() {
1373 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "oneParameter", singletonArray(null), singletonArray(String.class));
1374 }
1375
1376 @Test
1377 void testVarargsOverloadingResolution() {
1378
1379
1380
1381 assertEquals("Byte...", TestBean.varOverload((byte) 1, (byte) 2));
1382 assertEquals("Short...", TestBean.varOverload((short) 1, (short) 2));
1383 assertEquals("Integer...", TestBean.varOverload(1, 2));
1384 assertEquals("Long...", TestBean.varOverload(1L, 2L));
1385 assertEquals("Float...", TestBean.varOverload(1f, 2f));
1386 assertEquals("Double...", TestBean.varOverload(1d, 2d));
1387 assertEquals("Character...", TestBean.varOverload('a', 'b'));
1388 assertEquals("String...", TestBean.varOverload("a", "b"));
1389 assertEquals("Boolean...", TestBean.varOverload(true, false));
1390 assertEquals("Object...", TestBean.varOverload(1, "s"));
1391 assertEquals("Object...", TestBean.varOverload(1, true));
1392 assertEquals("Object...", TestBean.varOverload(1.1, true));
1393 assertEquals("Object...", TestBean.varOverload('c', true));
1394 assertEquals("Number...", TestBean.varOverload(1, 1.1));
1395 assertEquals("Number...", TestBean.varOverload(1, 1L));
1396 assertEquals("Number...", TestBean.varOverload(1d, 1f));
1397 assertEquals("Number...", TestBean.varOverload((short) 1, (byte) 1));
1398 assertEquals("Object...", TestBean.varOverload(1, 'c'));
1399 assertEquals("Object...", TestBean.varOverload('c', "s"));
1400 }
1401
1402 private String toString(final Class<?>[] c) {
1403 return Arrays.asList(c).toString();
1404 }
1405 }